From a3545767b48893273f51945ee72426dbd1a15ee2 Mon Sep 17 00:00:00 2001 From: Larry Knox Date: Tue, 7 May 2024 15:55:06 -0500 Subject: [PATCH] Sync develop changes April 22 - May 7 to hdf5_1_14 (#4465) * Split H5Tconv.c into modules by type (#4393) * Split H5Tconv.c into modules by type * Add new H5Tconv headers to list of private headers * Fix broken links in VOL API table (#4438) * Don't print thread ID when the library isn't multithreaded. (#4428) Corresponding changes to make error output for regression tests agnostic to thread setting. Signed-off-by: Quincey Koziol * Start refactoring H5E code to avoid using IDs internally (#4427) * Add support for builtin_expect compiler hint (#4425) * Add support for __builtin_expect extension And H5_LIKELY / H5_UNLIKELY macros to wrap it Signed-off-by: Quincey Koziol * Committing clang-format changes --------- Signed-off-by: Quincey Koziol Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * sanitizer flags need set before compiler flags (#4444) * Add navigate chapters and use release_docs in Learn Basics (#4441) * Fix for github issue #3790: infinite loop closing library (#4445) * Fix for github issue #3790: infinite loop closing library Cause of the problem: When h5dump tries to open the user provided test file, the metadata cache will call the "get_final_load_size" callback to find out the actual size of the the root object header. The callback function will call H5O__prefix_deserialize() to allocate space for the object header data structure (via H5FL_CALLOC) and to deserialize the object header prefix in order to find the actual size of the object header. The metadata cache will then check whether the actual size obtained will exceed the file's EOA. Since the actual size obtained from the test file exceeds the EOA, the metadata cache throws an error and return. However, the oh structure that was allocated in H5O__prefix_deserialize() was not freed and hence causing the problem described in this issue. Fix: 1) Deallocate the oh structure after obtaining and saving the needed information in udata which will be used later on in the "verify_chksum" callback. 2) Deserialize the object header prefix in the "object header's "deserialize" callback regardless. The original coding intends to keep the deserialized prefix so that the object header's "deserialize" callback does not need to deserialize the prefix again if the object header is coming through the "get_final_load_size" callback. * H5R Fortran wrappers and misc. H5R API/DOC updates (#4446) - Add Fortran H5R APIs: h5rcreate_attr_f, h5rcreate_object_f, h5rcreate_region_f, h5ropen_attr_f, h5ropen_object_f, h5ropen_region_f, h5rget_file_name_f, h5rget_attr_name_f, h5rget_obj_name_f, h5rcopy_f, h5requal_f, h5rdestroy_f, h5rget_type_f - Fixed function H5Requal actually to compare the reference pointers Fixed an issue with H5Requal always returning true because the function was only comparing the ref2_ptr to itself. * Fix heap-buffer-overflow in H5Fio.c (#4450) The buffer size for checksum was smaller than H5_SIZEOF_CHKSUM, causing an overflow while calculating the offset to the checksum in the buffer. A check was added so H5F_get_checksums would fail appropriately in all of its occurrences. Fix gh-4434 * Fix grammar in VOL guide (#4452) * Fix bug in MPI-IO VFD (#4456) Corrects incorrect usage of the vector_was_sorted parameter in H5FD__mpio_vector_build_types() * Bump the github-actions group with 3 updates (#4455) Bumps the github-actions group with 3 updates: [actions/download-artifact](https://github.com/actions/download-artifact), [peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages) and [github/codeql-action](https://github.com/github/codeql-action). Updates `actions/download-artifact` from 4.1.4 to 4.1.7 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/c850b930e6ba138125429b7e5c93fc707a7f8427...65a9edc5881444af0b9093a5e628f2fe47ea3b2e) Updates `peaceiris/actions-gh-pages` from 3.9.3 to 4.0.0 - [Release notes](https://github.com/peaceiris/actions-gh-pages/releases) - [Changelog](https://github.com/peaceiris/actions-gh-pages/blob/main/CHANGELOG.md) - [Commits](https://github.com/peaceiris/actions-gh-pages/compare/373f7f263a76c20808c831209c920827a82a2847...4f9cc6602d3f66b9c108549d475ec49e8ef4d45e) Updates `github/codeql-action` from 3.24.9 to 3.25.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/1b1aada464948af03b950897e5eb522f92603cc2...d39d31e687223d841ef683f52467bd88e9b21c14) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: peaceiris/actions-gh-pages dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fixed failures with xl compilers. (#4458) * type cast constant * fixed return types * Convert ERR test to use grep (#4451) * Convert ERR test to use grep * Eliminate use of .err files in CMake * Show error output if grep fails * Turn off cuda in NVHPC CI * Removed "function/code stack" debugging configure option (#4454) Easily replaced w/third-party tools, e.g. libbacktrace (https://github.com/ianlancetaylor/libbacktrace) * Clean up memory leaks in t_vfd (#4457) * Fixes and cleanup for ph5diff (#4460) * Fixes and cleanup for ph5diff Fixes concurrency issues in ph5diff that can cause interleaved output Fixes an issue where output can sometimes be dropped if it ended up in ph5diff's output overflow file Fixes an issue where MPI_Init is called after HDF5 has been initialized, preventing the library from setting up an MPI attribute to perform cleanup on MPI_Finalize Fixes an issue in config/cmake/runTest.cmake where the CMake logic would try to access an invalid list index if the number of lines in a test's output and reference files don't match * Add release note * Remove use of err files in autotools test scripts (#4461) * Fix typo in H5Rget_obj_type (#4463) Issue GH-1723 * Use ADD_H5_ERR_TEST to not compare output (#4464) --- .gitattributes | 1 - .github/workflows/abi-report.yml | 2 +- .github/workflows/cmake-bintest.yml | 6 +- .github/workflows/cmake-ctest.yml | 12 +- .github/workflows/nvhpc-cmake.yml | 1 + .github/workflows/release-files.yml | 28 +- .github/workflows/scorecard.yml | 2 +- CMakeLists.txt | 72 +- bin/make_err | 35 +- bin/trace | 2 - config/cmake/ConfigureChecks.cmake | 11 +- config/cmake/H5pubconf.h.in | 6 +- config/cmake/HDF5DeveloperBuild.cmake | 13 +- config/cmake/HDFTests.c | 15 + config/cmake/ZLIB/CMakeLists.txt | 2 +- config/cmake/grepTest.cmake | 43 +- config/cmake/libhdf5.settings.cmake.in | 1 - config/cmake/runTest.cmake | 25 +- config/sanitizer/sanitizers.cmake | 77 +- configure.ac | 44 +- doxygen/CMakeLists.txt | 2 +- doxygen/aliases | 4 + doxygen/dox/APIVersions.dox | 2 +- doxygen/dox/LearnBasics1.dox | 19 + doxygen/dox/LearnBasics2.dox | 10 + doxygen/dox/LearnBasics3.dox | 31 +- doxygen/dox/TrainingVideos.dox | 2 + doxygen/dox/VOLConnGuide.dox | 2 +- doxygen/examples/h5_attribute.c | 293 + doxygen/examples/h5_extlink.c | 662 ++ doxygen/examples/tables/volAPIs.dox | 4 +- fortran/src/H5Rff.F90 | 622 +- fortran/src/H5Sff.F90 | 2 +- fortran/src/H5_f.c | 10 +- fortran/src/H5_ff.F90 | 14 +- fortran/src/H5f90global.F90 | 25 +- fortran/src/hdf5_fortrandll.def.in | 13 + fortran/test/fortranlib_test.F90 | 5 + fortran/test/tH5R.F90 | 394 +- java/test/junit.sh.in | 86 +- release_docs/INSTALL_CMake.txt | 1 - release_docs/RELEASE.txt | 83 +- src/CMakeLists.txt | 31 +- src/H5B2cache.c | 18 +- src/H5CS.c | 293 - src/H5E.c | 83 +- src/H5EAcache.c | 30 +- src/H5Eint.c | 150 +- src/H5Epkg.h | 14 +- src/H5Eprivate.h | 2 +- src/H5FAcache.c | 18 +- src/H5FDmpio.c | 4 +- src/H5FL.c | 375 +- src/H5FLprivate.h | 101 +- src/H5FScache.c | 12 +- src/H5Fio.c | 11 +- src/H5Fpublic.h | 16 +- src/H5Fsuper_cache.c | 6 +- src/H5HFcache.c | 12 +- src/H5Ipublic.h | 12 +- src/H5Ocache.c | 78 +- src/H5Oint.c | 2 +- src/H5Opkg.h | 2 +- src/H5Ppublic.h | 20 +- src/H5R.c | 2 +- src/H5Rpublic.h | 85 +- src/H5SMcache.c | 12 +- src/H5T.c | 37 +- src/H5Tconv.c | 9897 +---------------- src/H5Tconv.h | 195 + src/H5Tconv_array.c | 234 + src/H5Tconv_array.h | 36 + src/H5Tconv_bitfield.c | 268 + src/H5Tconv_bitfield.h | 36 + src/H5Tconv_compound.c | 926 ++ src/H5Tconv_compound.h | 41 + src/H5Tconv_enum.c | 544 + src/H5Tconv_enum.h | 41 + src/H5Tconv_float.c | 2298 ++++ src/H5Tconv_float.h | 215 + src/H5Tconv_integer.c | 3181 ++++++ src/H5Tconv_integer.h | 471 + src/H5Tconv_macros.h | 1147 ++ src/H5Tconv_reference.c | 307 + src/H5Tconv_reference.h | 36 + src/H5Tconv_string.c | 267 + src/{H5CSprivate.h => H5Tconv_string.h} | 34 +- src/H5Tconv_vlen.c | 590 + src/H5Tconv_vlen.h | 36 + src/H5Tdbg.c | 6 +- src/H5Tpkg.h | 715 +- src/H5Tprivate.h | 69 +- src/H5build_settings.autotools.c.in | 1 - src/H5build_settings.cmake.c.in | 1 - src/H5private.h | 103 +- src/Makefile.am | 3 +- src/libhdf5.settings.in | 1 - test/cmpd_dset.c | 1 + test/h5test.c | 6 +- test/test_error.sh.in | 2 +- test/testfiles/err_compat_1 | 8 +- test/testfiles/error_test_1 | 12 +- test/trefer.c | 47 +- testpar/t_vfd.c | 87 +- tools/lib/h5diff.c | 659 +- tools/src/h5diff/ph5diff_main.c | 60 +- tools/test/h5copy/CMakeTests.cmake | 1 - tools/test/h5copy/expected/h5copy_misc1.err | 1 - tools/test/h5copy/testh5copy.sh.in | 136 +- tools/test/h5diff/CMakeTests.cmake | 84 +- tools/test/h5diff/expected/dangling_link.err | 4 - tools/test/h5diff/expected/h5diff_601_ERR.err | 4 - tools/test/h5diff/expected/h5diff_udfail.err | 12 - tools/test/h5diff/h5diff_plugin.sh.in | 88 - tools/test/h5diff/testh5diff.sh.in | 5 +- tools/test/h5dump/CMakeTests.cmake | 53 +- tools/test/h5dump/CMakeTestsPBITS.cmake | 167 +- tools/test/h5dump/CMakeTestsVDS.cmake | 5 - tools/test/h5dump/errfiles/filter_fail.err | 33 - tools/test/h5dump/errfiles/non_existing.err | 1 - .../pbits/tnofilename-with-packed-bits.err | 1 - .../pbits/tpbitsCharLengthExceeded.err | 1 - .../pbits/tpbitsCharOffsetExceeded.err | 1 - .../errfiles/pbits/tpbitsIncomplete.err | 1 - .../pbits/tpbitsIntLengthExceeded.err | 1 - .../pbits/tpbitsIntOffsetExceeded.err | 1 - .../errfiles/pbits/tpbitsLengthExceeded.err | 1 - .../errfiles/pbits/tpbitsLengthPositive.err | 1 - .../pbits/tpbitsLongLengthExceeded.err | 1 - .../pbits/tpbitsLongOffsetExceeded.err | 1 - .../errfiles/pbits/tpbitsMaxExceeded.err | 1 - .../errfiles/pbits/tpbitsOffsetExceeded.err | 1 - .../errfiles/pbits/tpbitsOffsetNegative.err | 1 - tools/test/h5dump/errfiles/tall-1.err | 37 - tools/test/h5dump/errfiles/tall-2A.err | 37 - tools/test/h5dump/errfiles/tall-2A0.err | 37 - tools/test/h5dump/errfiles/tall-2B.err | 37 - tools/test/h5dump/errfiles/tarray1_big.err | 31 - tools/test/h5dump/errfiles/tattr-3.err | 26 - tools/test/h5dump/errfiles/tattrregR.err | 21 - tools/test/h5dump/errfiles/tcomp-3.err | 31 - tools/test/h5dump/errfiles/tdataregR.err | 21 - tools/test/h5dump/errfiles/tdset-2.err | 57 - .../test/h5dump/errfiles/texceedsubblock.err | 1 - .../test/h5dump/errfiles/texceedsubcount.err | 1 - .../test/h5dump/errfiles/texceedsubstart.err | 1 - .../test/h5dump/errfiles/texceedsubstride.err | 1 - tools/test/h5dump/errfiles/textlink.err | 74 - tools/test/h5dump/errfiles/textlinkfar.err | 255 - tools/test/h5dump/errfiles/textlinksrc.err | 255 - tools/test/h5dump/errfiles/tgroup-2.err | 32 - tools/test/h5dump/errfiles/torderlinks1.err | 37 - tools/test/h5dump/errfiles/torderlinks2.err | 37 - tools/test/h5dump/errfiles/tperror.err | 57 - tools/test/h5dump/errfiles/tqmarkfile.err | 33 - tools/test/h5dump/errfiles/tslink-D.err | 40 - tools/test/h5dump/expected/infinite_loop.ddl | 0 .../h5dump/testfiles/3790_infinite_loop.h5 | Bin 0 -> 829 bytes tools/test/h5dump/testh5dump.sh.in | 263 +- tools/test/h5dump/testh5dumppbits.sh.in | 274 +- tools/test/h5dump/testh5dumpvds.sh.in | 240 +- tools/test/h5format_convert/CMakeTests.cmake | 13 +- tools/test/h5format_convert/testh5fc.sh.in | 41 +- tools/test/h5ls/CMakeTests.cmake | 10 - tools/test/h5ls/errfiles/nosuchfile.err | 1 - .../h5ls/errfiles/textlinksrc-nodangle-1.err | 2 - tools/test/h5ls/errfiles/tgroup-1.err | 2 - tools/test/h5ls/testh5ls.sh.in | 8 - ...ack_layout.h5-dset2_chunk_20x10-errstk.tst | 4 +- tools/test/h5repack/h5repack.sh.in | 2 +- tools/test/h5stat/CMakeTests.cmake | 72 +- .../test/h5stat/expected/h5stat_err1_dims.err | 1 - .../h5stat/expected/h5stat_err1_links.err | 1 - .../h5stat/expected/h5stat_err1_numattrs.err | 1 - .../h5stat/expected/h5stat_err2_numattrs.err | 1 - .../h5stat/expected/h5stat_err_old_fill.err | 1 - .../h5stat/expected/h5stat_err_old_layout.err | 1 - .../h5stat/expected/h5stat_err_refcount.err | 1 - tools/test/h5stat/expected/h5stat_nofile.err | 1 - .../test/h5stat/expected/h5stat_notexist.err | 1 - tools/test/h5stat/testh5stat.sh.in | 82 +- tools/test/misc/CMakeTestsClear.cmake | 7 - .../misc/expected/h5clear_missing_file.err | 1 - .../misc/expected/h5clear_no_mdc_image.err | 1 - .../test/misc/expected/h5clear_open_fail.err | 1 - tools/test/misc/testh5clear.sh.in | 46 +- 186 files changed, 14908 insertions(+), 14628 deletions(-) create mode 100644 doxygen/examples/h5_attribute.c create mode 100644 doxygen/examples/h5_extlink.c delete mode 100644 src/H5CS.c create mode 100644 src/H5Tconv.h create mode 100644 src/H5Tconv_array.c create mode 100644 src/H5Tconv_array.h create mode 100644 src/H5Tconv_bitfield.c create mode 100644 src/H5Tconv_bitfield.h create mode 100644 src/H5Tconv_compound.c create mode 100644 src/H5Tconv_compound.h create mode 100644 src/H5Tconv_enum.c create mode 100644 src/H5Tconv_enum.h create mode 100644 src/H5Tconv_float.c create mode 100644 src/H5Tconv_float.h create mode 100644 src/H5Tconv_integer.c create mode 100644 src/H5Tconv_integer.h create mode 100644 src/H5Tconv_macros.h create mode 100644 src/H5Tconv_reference.c create mode 100644 src/H5Tconv_reference.h create mode 100644 src/H5Tconv_string.c rename src/{H5CSprivate.h => H5Tconv_string.h} (54%) create mode 100644 src/H5Tconv_vlen.c create mode 100644 src/H5Tconv_vlen.h delete mode 100644 tools/test/h5copy/expected/h5copy_misc1.err delete mode 100644 tools/test/h5diff/expected/dangling_link.err delete mode 100644 tools/test/h5diff/expected/h5diff_601_ERR.err delete mode 100644 tools/test/h5diff/expected/h5diff_udfail.err delete mode 100644 tools/test/h5dump/errfiles/filter_fail.err delete mode 100644 tools/test/h5dump/errfiles/non_existing.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tnofilename-with-packed-bits.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsCharLengthExceeded.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsCharOffsetExceeded.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsIncomplete.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsIntLengthExceeded.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsIntOffsetExceeded.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsLengthExceeded.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsLengthPositive.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsLongLengthExceeded.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsLongOffsetExceeded.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsMaxExceeded.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsOffsetExceeded.err delete mode 100644 tools/test/h5dump/errfiles/pbits/tpbitsOffsetNegative.err delete mode 100644 tools/test/h5dump/errfiles/tall-1.err delete mode 100644 tools/test/h5dump/errfiles/tall-2A.err delete mode 100644 tools/test/h5dump/errfiles/tall-2A0.err delete mode 100644 tools/test/h5dump/errfiles/tall-2B.err delete mode 100644 tools/test/h5dump/errfiles/tarray1_big.err delete mode 100644 tools/test/h5dump/errfiles/tattr-3.err delete mode 100644 tools/test/h5dump/errfiles/tattrregR.err delete mode 100644 tools/test/h5dump/errfiles/tcomp-3.err delete mode 100644 tools/test/h5dump/errfiles/tdataregR.err delete mode 100644 tools/test/h5dump/errfiles/tdset-2.err delete mode 100644 tools/test/h5dump/errfiles/texceedsubblock.err delete mode 100644 tools/test/h5dump/errfiles/texceedsubcount.err delete mode 100644 tools/test/h5dump/errfiles/texceedsubstart.err delete mode 100644 tools/test/h5dump/errfiles/texceedsubstride.err delete mode 100644 tools/test/h5dump/errfiles/textlink.err delete mode 100644 tools/test/h5dump/errfiles/textlinkfar.err delete mode 100644 tools/test/h5dump/errfiles/textlinksrc.err delete mode 100644 tools/test/h5dump/errfiles/tgroup-2.err delete mode 100644 tools/test/h5dump/errfiles/torderlinks1.err delete mode 100644 tools/test/h5dump/errfiles/torderlinks2.err delete mode 100644 tools/test/h5dump/errfiles/tperror.err delete mode 100644 tools/test/h5dump/errfiles/tqmarkfile.err delete mode 100644 tools/test/h5dump/errfiles/tslink-D.err create mode 100644 tools/test/h5dump/expected/infinite_loop.ddl create mode 100644 tools/test/h5dump/testfiles/3790_infinite_loop.h5 delete mode 100644 tools/test/h5ls/errfiles/nosuchfile.err delete mode 100644 tools/test/h5ls/errfiles/textlinksrc-nodangle-1.err delete mode 100644 tools/test/h5ls/errfiles/tgroup-1.err delete mode 100644 tools/test/h5stat/expected/h5stat_err1_dims.err delete mode 100644 tools/test/h5stat/expected/h5stat_err1_links.err delete mode 100644 tools/test/h5stat/expected/h5stat_err1_numattrs.err delete mode 100644 tools/test/h5stat/expected/h5stat_err2_numattrs.err delete mode 100644 tools/test/h5stat/expected/h5stat_err_old_fill.err delete mode 100644 tools/test/h5stat/expected/h5stat_err_old_layout.err delete mode 100644 tools/test/h5stat/expected/h5stat_err_refcount.err delete mode 100644 tools/test/h5stat/expected/h5stat_nofile.err delete mode 100644 tools/test/h5stat/expected/h5stat_notexist.err delete mode 100644 tools/test/misc/expected/h5clear_missing_file.err delete mode 100644 tools/test/misc/expected/h5clear_no_mdc_image.err delete mode 100644 tools/test/misc/expected/h5clear_open_fail.err diff --git a/.gitattributes b/.gitattributes index 084de90778c..b03dddfc95d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -573,7 +573,6 @@ tools/h5diff/testfiles/tmpSingleSiteBethe.output.h5 -text tools/h5diff/testfiles/tmpSingleSiteBethe.reference.h5 -text tools/h5diff/testfiles/tmptest.he5 -text tools/h5diff/testfiles/tmptest2.he5 -text -tools/h5dump/errfiles/non_existing.err -text tools/h5format_convert/CMakeLists.txt -text tools/h5format_convert/CMakeTests.cmake -text tools/h5format_convert/Makefile.am -text diff --git a/.github/workflows/abi-report.yml b/.github/workflows/abi-report.yml index e14d83102e4..4736dc5adb4 100644 --- a/.github/workflows/abi-report.yml +++ b/.github/workflows/abi-report.yml @@ -46,7 +46,7 @@ jobs: - uses: actions/checkout@v4.1.1 - name: Get published binary (Linux) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-ubuntu-2204_gcc-binary path: ${{ github.workspace }} diff --git a/.github/workflows/cmake-bintest.yml b/.github/workflows/cmake-bintest.yml index fd6f84bad69..48be210173b 100644 --- a/.github/workflows/cmake-bintest.yml +++ b/.github/workflows/cmake-bintest.yml @@ -35,7 +35,7 @@ jobs: # Get files created by cmake-ctest script - name: Get published binary (Windows) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: zip-vs2022_cl-${{ inputs.build_mode }}-binary path: ${{ github.workspace }}/hdf5 @@ -109,7 +109,7 @@ jobs: distribution: 'temurin' - name: Get published binary (Linux) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-ubuntu-2204_gcc-${{ inputs.build_mode }}-binary path: ${{ github.workspace }} @@ -161,7 +161,7 @@ jobs: distribution: 'temurin' - name: Get published binary (MacOS) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-osx12-${{ inputs.build_mode }}-binary path: ${{ github.workspace }} diff --git a/.github/workflows/cmake-ctest.yml b/.github/workflows/cmake-ctest.yml index 19197ae5762..1a69de624e6 100644 --- a/.github/workflows/cmake-ctest.yml +++ b/.github/workflows/cmake-ctest.yml @@ -62,7 +62,7 @@ jobs: # Get files created by release script - name: Get zip-tarball (Windows) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: zip-tarball path: ${{ github.workspace }} @@ -146,7 +146,7 @@ jobs: # Get files created by release script - name: Get tgz-tarball (Linux) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-tarball path: ${{ github.workspace }} @@ -270,7 +270,7 @@ jobs: # Get files created by release script - name: Get tgz-tarball (MacOS) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-tarball path: ${{ github.workspace }} @@ -351,7 +351,7 @@ jobs: # Get files created by release script - name: Get tgz-tarball (Linux S3) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-tarball path: ${{ github.workspace }} @@ -432,7 +432,7 @@ jobs: # Get files created by release script - name: Get zip-tarball (Windows_intel) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: zip-tarball path: ${{ github.workspace }} @@ -527,7 +527,7 @@ jobs: # Get files created by release script - name: Get tgz-tarball (Linux_intel) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-tarball path: ${{ github.workspace }} diff --git a/.github/workflows/nvhpc-cmake.yml b/.github/workflows/nvhpc-cmake.yml index 0473f572df7..e365bdab62f 100644 --- a/.github/workflows/nvhpc-cmake.yml +++ b/.github/workflows/nvhpc-cmake.yml @@ -59,6 +59,7 @@ jobs: -DHDF5_BUILD_FORTRAN:BOOL=ON \ -DHDF5_BUILD_JAVA:BOOL=OFF \ -DMPIEXEC_MAX_NUMPROCS:STRING="2" \ + -DMPIEXEC_PREFLAGS:STRING="--mca;opal_warn_on_missing_libcuda;0" \ $GITHUB_WORKSPACE - name: CMake Build diff --git a/.github/workflows/release-files.yml b/.github/workflows/release-files.yml index aba0e9efd00..e4d1a093af7 100644 --- a/.github/workflows/release-files.yml +++ b/.github/workflows/release-files.yml @@ -73,7 +73,7 @@ jobs: # Get files created by tarball script - name: Get doxygen (Linux) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: docs-doxygen path: ${{ github.workspace }}/${{ steps.get-file-base.outputs.FILE_BASE }}.doxygen @@ -82,68 +82,68 @@ jobs: run: zip -r ${{ steps.get-file-base.outputs.FILE_BASE }}.doxygen.zip ./${{ steps.get-file-base.outputs.FILE_BASE }}.doxygen - name: Get tgz-tarball (Linux) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-tarball path: ${{ github.workspace }} - name: Get zip-tarball (Windows) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: zip-tarball path: ${{ github.workspace }} # Get files created by cmake-ctest script - name: Get published binary (Windows) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: zip-vs2022_cl-binary path: ${{ github.workspace }} - name: Get published binary (MacOS) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-osx12-binary path: ${{ github.workspace }} - name: Get published binary (Linux) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-ubuntu-2204_gcc-binary path: ${{ github.workspace }} - name: Get published deb binary (Linux) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: deb-ubuntu-2204_gcc-binary path: ${{ github.workspace }} - name: Get published rpm binary (Linux) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: rpm-ubuntu-2204_gcc-binary path: ${{ github.workspace }} - name: Get published binary (Linux S3) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-ubuntu-2204_gcc_s3-binary path: ${{ github.workspace }} - name: Get published binary (Windows_intel) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: zip-vs2022_intel-binary path: ${{ github.workspace }} - name: Get published binary (Linux_intel) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tgz-ubuntu-2204_intel-binary path: ${{ github.workspace }} - name: Get published abi reports (Linux) - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: abi-reports path: ${{ github.workspace }} @@ -168,7 +168,7 @@ jobs: echo "${{ steps.get-file-base.outputs.FILE_BASE }}" > ./last-file.txt - name: Get NEWSLETTER - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: NEWSLETTER path: ${{ github.workspace }} @@ -232,7 +232,7 @@ jobs: ls ${{ runner.workspace }} - name: branch-only-docs - uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3.9.3 + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ${{ github.workspace }}/${{ steps.get-file-base.outputs.FILE_BASE }}.doxygen diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 338cac1b096..10e50caef1d 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -67,6 +67,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: results.sarif diff --git a/CMakeLists.txt b/CMakeLists.txt index ec1ecae58ef..ee65c2a607d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -533,6 +533,42 @@ if (BUILD_STATIC_EXECS) endif () endif () +option (HDF5_ENABLE_ANALYZER_TOOLS "enable the use of Clang tools" OFF) +mark_as_advanced (HDF5_ENABLE_ANALYZER_TOOLS) +if (HDF5_ENABLE_ANALYZER_TOOLS) + include (${HDF5_SOURCE_DIR}/config/sanitizer/tools.cmake) +endif () +option (HDF5_ENABLE_SANITIZERS "execute the Clang sanitizer" OFF) +mark_as_advanced (HDF5_ENABLE_SANITIZERS) +if (HDF5_ENABLE_SANITIZERS) + include (${HDF5_SOURCE_DIR}/config/sanitizer/sanitizers.cmake) +endif () +option (HDF5_ENABLE_FORMATTERS "format source files" OFF) +mark_as_advanced (HDF5_ENABLE_FORMATTERS) +if (HDF5_ENABLE_FORMATTERS) + include (${HDF5_SOURCE_DIR}/config/sanitizer/formatting.cmake) +endif () + +#----------------------------------------------------------------------------- +# Option to use code coverage +#----------------------------------------------------------------------------- +option (HDF5_ENABLE_COVERAGE "Enable code coverage for Libraries and Programs" OFF) +if (HDF5_ENABLE_COVERAGE) + include (${HDF5_SOURCE_DIR}/config/sanitizer/code-coverage.cmake) + if(CODE_COVERAGE AND CODE_COVERAGE_ADDED) + add_code_coverage () # Adds instrumentation to all targets + else () + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 --coverage -fprofile-arcs -ftest-coverage") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g --coverage -O0 -fprofile-arcs -ftest-coverage") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + set (LDFLAGS "${LDFLAGS} -fprofile-arcs -ftest-coverage") + link_libraries (gcov) + else () + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + endif () + endif () +endif () + #----------------------------------------------------------------------------- # Option to indicate using a memory checker #----------------------------------------------------------------------------- @@ -1139,40 +1175,4 @@ if (EXISTS "${HDF5_SOURCE_DIR}/HDF5Examples" AND IS_DIRECTORY "${HDF5_SOURCE_DIR endif () endif () -option (HDF5_ENABLE_ANALYZER_TOOLS "enable the use of Clang tools" OFF) -mark_as_advanced (HDF5_ENABLE_ANALYZER_TOOLS) -if (HDF5_ENABLE_ANALYZER_TOOLS) - include (${HDF5_SOURCE_DIR}/config/sanitizer/tools.cmake) -endif () -option (HDF5_ENABLE_SANITIZERS "execute the Clang sanitizer" OFF) -mark_as_advanced (HDF5_ENABLE_SANITIZERS) -if (HDF5_ENABLE_SANITIZERS) - include (${HDF5_SOURCE_DIR}/config/sanitizer/sanitizers.cmake) -endif () -option (HDF5_ENABLE_FORMATTERS "format source files" OFF) -mark_as_advanced (HDF5_ENABLE_FORMATTERS) -if (HDF5_ENABLE_FORMATTERS) - include (${HDF5_SOURCE_DIR}/config/sanitizer/formatting.cmake) -endif () - -#----------------------------------------------------------------------------- -# Option to use code coverage -#----------------------------------------------------------------------------- -option (HDF5_ENABLE_COVERAGE "Enable code coverage for Libraries and Programs" OFF) -if (HDF5_ENABLE_COVERAGE) - include (${HDF5_SOURCE_DIR}/config/sanitizer/code-coverage.cmake) - if(CODE_COVERAGE AND CODE_COVERAGE_ADDED) - add_code_coverage () # Adds instrumentation to all targets - else () - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 --coverage -fprofile-arcs -ftest-coverage") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g --coverage -O0 -fprofile-arcs -ftest-coverage") - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - set (LDFLAGS "${LDFLAGS} -fprofile-arcs -ftest-coverage") - link_libraries (gcov) - else () - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") - endif () - endif () -endif () - include (CMakeInstallation.cmake) diff --git a/bin/make_err b/bin/make_err index 064d66c9456..618a2df46ac 100755 --- a/bin/make_err +++ b/bin/make_err @@ -223,6 +223,8 @@ sub create_init ($) { my $desc; # Description of error message my $sect_name; # Section of minor error messages my $sect_desc; # Description of section + my $first_major = 0; # Whether the first major error code was saved + my $first_minor = 0; # Whether the first minor error code was saved # Rename previous file # rename "${prefix}${file}", "${prefix}${file}~" or die "unable to make backup"; @@ -241,12 +243,22 @@ sub create_init ($) { print HEADER "/* Major error codes */\n"; print HEADER "/*********************/\n\n"; foreach $name (keys %major) { - print HEADER " "x(0*$indent),"assert(${name}_g==(-1));\n"; + print HEADER " "x(0*$indent),"assert(${name}_g==H5I_INVALID_HID);\n"; print HEADER " "x(0*$indent),"if((msg = H5E__create_msg(cls, H5E_MAJOR, \"${major{$name}}\"))==NULL)\n"; print HEADER " "x(1*$indent),"HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, \"error message initialization failed\");\n"; print HEADER " "x(0*$indent),"if((${name}_g = H5I_register(H5I_ERROR_MSG, msg, false))<0)\n"; print HEADER " "x(1*$indent),"HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, \"can't register error message\");\n"; + if ($first_major == 0) { + print HEADER " "x(0*$indent),"\n/* Remember first major error code ID */\n"; + print HEADER " "x(0*$indent),"assert(H5E_first_maj_id_g==H5I_INVALID_HID);\n"; + print HEADER " "x(0*$indent),"H5E_first_maj_id_g = ${name}_g;\n\n"; + $first_major = 1; } + $last_name = $name; + } + print HEADER " "x(0*$indent),"\n/* Remember last major error code ID */\n"; + print HEADER " "x(0*$indent),"assert(H5E_last_maj_id_g==H5I_INVALID_HID);\n"; + print HEADER " "x(0*$indent),"H5E_last_maj_id_g = ${last_name}_g;\n\n"; # Iterate over all the minor error sections print HEADER "\n/*********************/\n"; @@ -257,13 +269,24 @@ sub create_init ($) { # Iterate over all the minor errors in each section for $name ( @{$section_list{$sect_name}}) { - print HEADER " "x(0*$indent),"assert(${name}_g==(-1));\n"; + print HEADER " "x(0*$indent),"assert(${name}_g==H5I_INVALID_HID);\n"; print HEADER " "x(0*$indent),"if((msg = H5E__create_msg(cls, H5E_MINOR, \"${minor{$name}}\"))==NULL)\n"; print HEADER " "x(1*$indent),"HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, \"error message initialization failed\");\n"; print HEADER " "x(0*$indent),"if((${name}_g = H5I_register(H5I_ERROR_MSG, msg, true))<0)\n"; print HEADER " "x(1*$indent),"HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, \"can't register error message\");\n"; + + if ($first_minor == 0) { + print HEADER " "x(0*$indent),"\n/* Remember first minor error code ID */\n"; + print HEADER " "x(0*$indent),"assert(H5E_first_min_id_g==H5I_INVALID_HID);\n"; + print HEADER " "x(0*$indent),"H5E_first_min_id_g = ${name}_g;\n\n"; + $first_minor = 1; + } + $last_name = $name; } } + print HEADER " "x(0*$indent),"\n/* Remember last minor error code ID */\n"; + print HEADER " "x(0*$indent),"assert(H5E_last_min_id_g==H5I_INVALID_HID);\n"; + print HEADER " "x(0*$indent),"H5E_last_min_id_g = ${last_name}_g;\n"; print_endprotect(*HEADER, $file); @@ -299,7 +322,9 @@ sub create_term ($) { foreach $name (keys %major) { print HEADER " "x($indent),"\n${name}_g="; } - print HEADER " (-1);\n"; + print HEADER " H5I_INVALID_HID;\n"; + print HEADER " "x(0*$indent),"H5E_first_maj_id_g = H5I_INVALID_HID;\n\n"; + print HEADER " "x(0*$indent),"H5E_last_maj_id_g = H5I_INVALID_HID;\n\n"; # Iterate over all the minor error sections print HEADER "\n/* Reset minor error IDs */\n"; @@ -311,7 +336,9 @@ sub create_term ($) { print HEADER " "x($indent),"\n${name}_g="; } } - print HEADER " (-1);\n"; + print HEADER " H5I_INVALID_HID;\n"; + print HEADER " "x(0*$indent),"H5E_first_min_id_g = H5I_INVALID_HID;\n\n"; + print HEADER " "x(0*$indent),"H5E_last_min_id_g = H5I_INVALID_HID;\n\n"; print_endprotect(*HEADER, $file); diff --git a/bin/trace b/bin/trace index f86b2ee7874..d37c87a596b 100755 --- a/bin/trace +++ b/bin/trace @@ -307,14 +307,12 @@ sub rewrite_func ($$$$$) { # First remove: # * /*in*/, /*out*/, /*in_out*/, and /*in,out*/ comments # * preprocessor lines that start with # - # * H5FL_TRACKING_PARAMS macros (free list code only) # # then split the function arguments on commas $args =~ s/\/\*\s*in\s*\*\///g; # Get rid of /*in*/ $args =~ s/\/\*\s*out\s*\*\///g; # Get rid of /*out*/ $args =~ s/\/\*\s*in,\s*out\s*\*\///g; # Get rid of /*in,out*/ $args =~ s/\/\*\s*in_out\s*\*\///g; # Get rid of /*in_out*/ - $args =~ s/H5FL_TRACK_PARAMS//g; # Remove free list macro $args =~ s/\n#.*?\n/\n/g; # Remove lines beginning with '#' my @args = split /,[\s\n]*/, $args; my $argno = 0; diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 4d27d662a65..e55f8bd29fe 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -436,6 +436,7 @@ endif () if (MINGW OR NOT WINDOWS) foreach (other_test HAVE_ATTRIBUTE + HAVE_BUILTIN_EXPECT SYSTEM_SCOPE_THREADS HAVE_SOCKLEN_T ) @@ -496,16 +497,6 @@ if (HDF5_WANT_DCONV_EXCEPTION) endif () MARK_AS_ADVANCED (HDF5_WANT_DCONV_EXCEPTION) -# ---------------------------------------------------------------------- -# Check if they would like the function stack support compiled in -#----------------------------------------------------------------------------- -option (HDF5_ENABLE_CODESTACK "Enable the function stack tracing (for developer debugging)." OFF) -mark_as_advanced (HDF5_ENABLE_CODESTACK) -if (HDF5_ENABLE_CODESTACK) - set (${HDF_PREFIX}_HAVE_CODESTACK 1) -endif () -MARK_AS_ADVANCED (HDF5_ENABLE_CODESTACK) - # ---------------------------------------------------------------------- # Check if they would like to show all warnings (not suppressed internally) #----------------------------------------------------------------------------- diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index cd898cdff21..e690e1ef265 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -110,9 +110,6 @@ /* Define to 1 if CLOCK_MONOTONIC_COARSE is available */ #cmakedefine H5_HAVE_CLOCK_MONOTONIC_COARSE @H5_HAVE_CLOCK_MONOTONIC_COARSE@ -/* Define if the function stack tracing code is to be compiled in */ -#cmakedefine H5_HAVE_CODESTACK @H5_HAVE_CODESTACK@ - /* Define to 1 if you have the header file. */ #cmakedefine H5_HAVE_CURL_CURL_H @H5_HAVE_CURL_H@ @@ -334,6 +331,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine H5_HAVE_SZLIB_H @H5_HAVE_SZLIB_H@ +/* Define to 1 if the compiler supports the __builtin_expect() extension */ +#cmakedefine H5_HAVE_BUILTIN_EXPECT @H5_HAVE_BUILTIN_EXPECT@ + #if defined(_WIN32) && !defined(H5_BUILT_AS_DYNAMIC_LIB) /* Not supported on WIN32 platforms with static linking */ /* #undef H5_HAVE_THREADSAFE */ diff --git a/config/cmake/HDF5DeveloperBuild.cmake b/config/cmake/HDF5DeveloperBuild.cmake index f8ccc2f7bef..a8c128d7e70 100644 --- a/config/cmake/HDF5DeveloperBuild.cmake +++ b/config/cmake/HDF5DeveloperBuild.cmake @@ -157,17 +157,6 @@ if (HDF5_ENABLE_DEBUG_H5C_SANITY_CHECKS) # list (APPEND HDF5_DEBUG_APIS H5C_DO_MEMORY_SANITY_CHECKS=1) endif () -option (HDF5_ENABLE_DEBUG_H5FL_TRACK "Enable tracking of free list allocations" OFF) -mark_as_advanced (HDF5_ENABLE_DEBUG_H5FL_TRACK) -if (HDF5_ENABLE_DEBUG_H5FL_TRACK) - list (APPEND HDF5_DEBUG_APIS H5FL_TRACK) - - # Free list tracking requires the codestack functionality - set (HDF5_ENABLE_CODESTACK ON CACHE BOOL "Enable the function stack tracing (for developer debugging)." FORCE) -else () - unset (HDF5_ENABLE_CODESTACK CACHE) -endif () - option (HDF5_ENABLE_DEBUG_H5FS_ASSERT "Enable extra debugging of H5FS module" OFF) mark_as_advanced (HDF5_ENABLE_DEBUG_H5FS_ASSERT) if (HDF5_ENABLE_DEBUG_H5FS_ASSERT) @@ -178,7 +167,7 @@ endif () # free lists entirely for developer build modes, as they can # make certain types of issues (like references to stale pointers) # much more difficult to debug -if (NOT HDF5_ENABLE_DEBUG_H5FL AND NOT HDF5_ENABLE_DEBUG_H5FL_TRACK) +if (NOT HDF5_ENABLE_DEBUG_H5FL) list (APPEND HDF5_DEVELOPER_DEFS H5_NO_FREE_LISTS) endif () diff --git a/config/cmake/HDFTests.c b/config/cmake/HDFTests.c index 0f0600abd81..8d0e78f46b7 100644 --- a/config/cmake/HDFTests.c +++ b/config/cmake/HDFTests.c @@ -15,6 +15,21 @@ #define SIMPLE_TEST(x) int main(void){ x; return 0; } +#ifdef HAVE_BUILTIN_EXPECT + +int +main () +{ + void *ptr = (void*) 0; + + if (__builtin_expect (ptr != (void*) 0, 1)) + return 0; + + return 0; +} + +#endif /* HAVE_BUILTIN_EXPECT */ + #ifdef HAVE_ATTRIBUTE int diff --git a/config/cmake/ZLIB/CMakeLists.txt b/config/cmake/ZLIB/CMakeLists.txt index 7b5d0cf62dd..e3c90b609d7 100644 --- a/config/cmake/ZLIB/CMakeLists.txt +++ b/config/cmake/ZLIB/CMakeLists.txt @@ -129,7 +129,7 @@ endif () # Compiler specific flags : Shouldn't there be compiler tests for these #----------------------------------------------------------------------------- if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - set (CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS} -Wno-strict-prototypes") + set (CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS} -Wno-strict-prototypes -Wno-implicit-function-declaration") endif () if (CMAKE_C_COMPILER_ID MATCHES "IntelLLVM" OR CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") set (CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS} -Wno-implicit-function-declaration") diff --git a/config/cmake/grepTest.cmake b/config/cmake/grepTest.cmake index 4031a1bde03..529649e4e7c 100644 --- a/config/cmake/grepTest.cmake +++ b/config/cmake/grepTest.cmake @@ -11,6 +11,7 @@ # # grepTest.cmake executes a command and captures the output in a file. File is then compared # against a reference file. Exit status of command can also be compared. +cmake_policy(SET CMP0007 NEW) # arguments checking if (NOT TEST_PROGRAM) @@ -67,6 +68,11 @@ execute_process ( message (STATUS "COMMAND Result: ${TEST_RESULT}") +# append the test result status with a predefined text +if (TEST_APPEND) + file (APPEND ${TEST_FOLDER}/${TEST_OUTPUT} "${TEST_APPEND} ${TEST_RESULT}\n") +endif () + message (STATUS "COMMAND Error: ${TEST_ERROR}") # remove special output @@ -75,15 +81,22 @@ if (EXISTS "${TEST_FOLDER}/${TEST_OUTPUT}") string (FIND "${TEST_STREAM}" "_pmi_alps" TEST_FIND_RESULT) if (TEST_FIND_RESULT GREATER -1) string (REGEX REPLACE "^.*_pmi_alps[^\n]+\n" "" TEST_STREAM "${TEST_STREAM}") - file (WRITE ${TEST_FOLDER}/${TEST_OUTPUT} "${TEST_STREAM}") + file (WRITE ${TEST_FOLDER}/${TEST_OUTPUT} ${TEST_STREAM}) endif () string (FIND "${TEST_STREAM}" "ulimit -s" TEST_FIND_RESULT) if (TEST_FIND_RESULT GREATER -1) string (REGEX REPLACE "^.*ulimit -s[^\n]+\n" "" TEST_STREAM "${TEST_STREAM}") - file (WRITE ${TEST_FOLDER}/${TEST_OUTPUT} "${TEST_STREAM}") + file (WRITE ${TEST_FOLDER}/${TEST_OUTPUT} ${TEST_STREAM}) endif () endif () +if (TEST_REF_FILTER) + #message (STATUS "TEST_REF_FILTER: ${TEST_APPEND}${TEST_REF_FILTER}") + file (READ ${TEST_FOLDER}/${TEST_REFERENCE} TEST_STREAM) + string (REGEX REPLACE "${TEST_REF_APPEND}" "${TEST_REF_FILTER}" TEST_STREAM "${TEST_STREAM}") + file (WRITE ${TEST_FOLDER}/${TEST_REFERENCE} "${TEST_STREAM}") +endif () + # if the TEST_ERRREF exists grep the error output with the error reference set (TEST_ERRREF_RESULT 0) if (TEST_ERRREF) @@ -96,26 +109,25 @@ if (TEST_ERRREF) string (REGEX MATCH "${TEST_ERRREF}" TEST_MATCH ${TEST_ERR_STREAM}) string (COMPARE EQUAL "${TEST_ERRREF}" "${TEST_MATCH}" TEST_ERRREF_RESULT) if (NOT TEST_ERRREF_RESULT) + # dump the output unless nodisplay option is set + if (NOT TEST_NO_DISPLAY) + execute_process ( + COMMAND ${CMAKE_COMMAND} -E echo ${TEST_ERR_STREAM} + RESULT_VARIABLE TEST_ERRREF_RESULT + ) + endif () message (FATAL_ERROR "Failed: The error output of ${TEST_PROGRAM} did not contain ${TEST_ERRREF}") endif () endif () endif () - #always compare output file to reference unless this must be skipped + # compare output files to references unless this must be skipped set (TEST_COMPARE_RESULT 0) if (NOT TEST_SKIP_COMPARE) if (EXISTS "${TEST_FOLDER}/${TEST_REFERENCE}") file (READ ${TEST_FOLDER}/${TEST_REFERENCE} TEST_STREAM) list (LENGTH TEST_STREAM test_len) if (test_len GREATER 0) - if (WIN32) - configure_file(${TEST_FOLDER}/${TEST_REFERENCE} ${TEST_FOLDER}/${TEST_REFERENCE}.tmp NEWLINE_STYLE CRLF) - if (EXISTS "${TEST_FOLDER}/${TEST_REFERENCE}.tmp") - file(RENAME ${TEST_FOLDER}/${TEST_REFERENCE}.tmp ${TEST_FOLDER}/${TEST_REFERENCE}) - endif () - #file (READ ${TEST_FOLDER}/${TEST_REFERENCE} TEST_STREAM) - #file (WRITE ${TEST_FOLDER}/${TEST_REFERENCE} "${TEST_STREAM}") - endif () if (NOT TEST_SORT_COMPARE) # now compare the output with the reference execute_process ( @@ -138,7 +150,14 @@ if (TEST_ERRREF) list (LENGTH test_act len_act) file (STRINGS ${TEST_FOLDER}/${TEST_REFERENCE} test_ref) list (LENGTH test_ref len_ref) + if (NOT len_act EQUAL len_ref) + set (TEST_COMPARE_RESULT 1) + endif () if (len_act GREATER 0 AND len_ref GREATER 0) + if (TEST_SORT_COMPARE) + list (SORT test_act) + list (SORT test_ref) + endif () math (EXPR _FP_LEN "${len_ref} - 1") foreach (line RANGE 0 ${_FP_LEN}) list (GET test_act ${line} str_act) @@ -200,7 +219,7 @@ if (TEST_FILTER) endif () if (NOT DEFINED ENV{HDF5_NOCLEANUP}) - if (EXISTS "${TEST_FOLDER}/${TEST_OUTPUT}") + if (EXISTS "${TEST_FOLDER}/${TEST_OUTPUT}" AND NOT TEST_SAVE) file (REMOVE ${TEST_FOLDER}/${TEST_OUTPUT}) endif () diff --git a/config/cmake/libhdf5.settings.cmake.in b/config/cmake/libhdf5.settings.cmake.in index deb07ed82d6..c9f3e4d413c 100644 --- a/config/cmake/libhdf5.settings.cmake.in +++ b/config/cmake/libhdf5.settings.cmake.in @@ -88,7 +88,6 @@ Dimension scales w/ new references: @DIMENSION_SCALES_WITH_NEW_REF@ Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@ API Tracing: @HDF5_ENABLE_TRACE@ Using memory checker: @HDF5_ENABLE_USING_MEMCHECKER@ - Function Stack Tracing: @HDF5_ENABLE_CODESTACK@ Use file locking: @HDF5_FILE_LOCKING_SETTING@ Strict File Format Checks: @HDF5_STRICT_FORMAT_CHECKS@ Optimization Instrumentation: @HDF5_Enable_Instrument@ diff --git a/config/cmake/runTest.cmake b/config/cmake/runTest.cmake index ff9732e0821..8eed074ecb6 100644 --- a/config/cmake/runTest.cmake +++ b/config/cmake/runTest.cmake @@ -49,7 +49,7 @@ endif () if (TEST_ENV_VAR) set (ENV{${TEST_ENV_VAR}} "${TEST_ENV_VALUE}") - #message (STATUS "ENV:${TEST_ENV_VAR}=$ENV{${TEST_ENV_VAR}}") + message (TRACE "ENV:${TEST_ENV_VAR}=$ENV{${TEST_ENV_VAR}}") endif () if (NOT TEST_INPUT) @@ -233,7 +233,6 @@ if (NOT TEST_SKIP_COMPARE) file (READ ${TEST_FOLDER}/${TEST_REFERENCE} TEST_STREAM) list (LENGTH TEST_STREAM test_len) if (test_len GREATER 0) - if (NOT TEST_SORT_COMPARE) # now compare the output with the reference execute_process ( @@ -266,12 +265,22 @@ if (NOT TEST_SKIP_COMPARE) endif () math (EXPR _FP_LEN "${len_ref} - 1") foreach (line RANGE 0 ${_FP_LEN}) - list (GET test_act ${line} str_act) - list (GET test_ref ${line} str_ref) - if (NOT str_act STREQUAL str_ref) - if (str_act) - set (TEST_COMPARE_RESULT 1) - message (STATUS "line = ${line}\n***ACTUAL: ${str_act}\n****REFER: ${str_ref}\n") + if (line GREATER_EQUAL len_act) + message (STATUS "COMPARE FAILED: ran out of lines in ${TEST_FOLDER}/${TEST_OUTPUT}") + set (TEST_COMPARE_RESULT 1) + break () + elseif (line GREATER_EQUAL len_ref) + message (STATUS "COMPARE FAILED: ran out of lines in ${TEST_FOLDER}/${TEST_REFERENCE}") + set (TEST_COMPARE_RESULT 1) + break () + else () + list (GET test_act ${line} str_act) + list (GET test_ref ${line} str_ref) + if (NOT str_act STREQUAL str_ref) + if (str_act) + set (TEST_COMPARE_RESULT 1) + message (STATUS "line = ${line}\n***ACTUAL: ${str_act}\n****REFER: ${str_ref}\n") + endif () endif () endif () endforeach () diff --git a/config/sanitizer/sanitizers.cmake b/config/sanitizer/sanitizers.cmake index 91768240fb2..dea9f099f06 100644 --- a/config/sanitizer/sanitizers.cmake +++ b/config/sanitizer/sanitizers.cmake @@ -51,9 +51,6 @@ function(test_san_flags return_var flags) endfunction() message(STATUS "USE_SANITIZER=${USE_SANITIZER}, CMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}") -if(CMAKE_CXX_COMPILER_LOADED) - message(STATUS "... CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}") -endif() if(USE_SANITIZER) if(CMAKE_C_COMPILER_ID MATCHES "IntelLLVM" OR CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -61,17 +58,11 @@ if(USE_SANITIZER) unset(SANITIZER_SELECTED_FLAGS) if(UNIX) - append("-fno-omit-frame-pointer" CMAKE_C_FLAGS) - message(STATUS "Building with sanitize, base flags=${CMAKE_C_SANITIZER_FLAGS}") - if (CMAKE_CXX_COMPILER_LOADED) - append("-fno-omit-frame-pointer" CMAKE_CXX_FLAGS) - endif () + append("-fno-omit-frame-pointer" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + message(STATUS "Building with sanitize, base flags=${CMAKE_C_FLAGS}") if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") - append("-O1" CMAKE_C_FLAGS) - if (CMAKE_CXX_COMPILER_LOADED) - append("-O1" CMAKE_CXX_FLAGS) - endif () + append("-O1" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() if(USE_SANITIZER MATCHES "([Aa]ddress)") @@ -84,10 +75,7 @@ if(USE_SANITIZER) append("${SANITIZER_ADDR_FLAG}" SANITIZER_SELECTED_FLAGS) if(AFL) - append_quoteless(AFL_USE_ASAN=1 CMAKE_C_COMPILER_LAUNCHER) - if (CMAKE_CXX_COMPILER_LOADED) - append_quoteless(AFL_USE_ASAN=1 CMAKE_CXX_COMPILER_LAUNCHER) - endif () + append_quoteless(AFL_USE_ASAN=1 CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER) endif() else() message(FATAL_ERROR "Address sanitizer not available for ${CMAKE_C_COMPILER}") @@ -115,10 +103,7 @@ if(USE_SANITIZER) append("${SANITIZER_MEM_FLAG}" SANITIZER_SELECTED_FLAGS) if(AFL) - append_quoteless(AFL_USE_MSAN=1 CMAKE_C_COMPILER_LAUNCHER) - if (CMAKE_CXX_COMPILER_LOADED) - append_quoteless(AFL_USE_MSAN=1 CMAKE_CXX_COMPILER_LAUNCHER) - endif () + append_quoteless(AFL_USE_MSAN=1 CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER) endif() else() message(FATAL_ERROR "Memory [With Origins] sanitizer not available for ${CMAKE_C_COMPILER}") @@ -140,16 +125,10 @@ if(USE_SANITIZER) append("${SANITIZER_UB_FLAG}" SANITIZER_SELECTED_FLAGS) if(AFL) - append_quoteless(AFL_USE_UBSAN=1 CMAKE_C_COMPILER_LAUNCHER) - if (CMAKE_CXX_COMPILER_LOADED) - append_quoteless(AFL_USE_UBSAN=1 CMAKE_CXX_COMPILER_LAUNCHER) - endif () + append_quoteless(AFL_USE_UBSAN=1 CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER) endif() else() message(FATAL_ERROR "Undefined Behaviour sanitizer not available for ${CMAKE_C_COMPILER}") - if (CMAKE_CXX_COMPILER_LOADED) - message(FATAL_ERROR "Undefined Behaviour sanitizer not available for ${CMAKE_CXX_COMPILER}") - endif () endif() endif() @@ -162,16 +141,10 @@ if(USE_SANITIZER) append("${SANITIZER_THREAD_FLAG}" SANITIZER_SELECTED_FLAGS) if(AFL) - append_quoteless(AFL_USE_TSAN=1 CMAKE_C_COMPILER_LAUNCHER) - if (CMAKE_CXX_COMPILER_LOADED) - append_quoteless(AFL_USE_TSAN=1 CMAKE_CXX_COMPILER_LAUNCHER) - endif () + append_quoteless(AFL_USE_TSAN=1 CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER) endif() else() message(FATAL_ERROR "Thread sanitizer not available for ${CMAKE_C_COMPILER}") - if (CMAKE_CXX_COMPILER_LOADED) - message(FATAL_ERROR "Thread sanitizer not available for ${CMAKE_CXX_COMPILER}") - endif () endif() endif() @@ -184,16 +157,10 @@ if(USE_SANITIZER) append("${SANITIZER_LEAK_FLAG}" SANITIZER_SELECTED_FLAGS) if(AFL) - append_quoteless(AFL_USE_LSAN=1 CMAKE_C_COMPILER_LAUNCHER) - if (CMAKE_CXX_COMPILER_LOADED) - append_quoteless(AFL_USE_LSAN=1 CMAKE_CXX_COMPILER_LAUNCHER) - endif () + append_quoteless(AFL_USE_LSAN=1 CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER) endif() else() message(FATAL_ERROR "Thread sanitizer not available for ${CMAKE_C_COMPILER}") - if (CMAKE_CXX_COMPILER_LOADED) - message(FATAL_ERROR "Thread sanitizer not available for ${CMAKE_CXX_COMPILER}") - endif () endif() endif() @@ -206,16 +173,10 @@ if(USE_SANITIZER) append("${SANITIZER_LEAK_FLAG}" SANITIZER_SELECTED_FLAGS) if(AFL) - append_quoteless(AFL_USE_CFISAN=1 CMAKE_C_COMPILER_LAUNCHER) - if (CMAKE_CXX_COMPILER_LOADED) - append_quoteless(AFL_USE_CFISAN=1 CMAKE_CXX_COMPILER_LAUNCHER) - endif () + append_quoteless(AFL_USE_CFISAN=1 CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER) endif() else() message(FATAL_ERROR "Control Flow Integrity(CFI) sanitizer not available for ${CMAKE_C_COMPILER}") - if (CMAKE_CXX_COMPILER_LOADED) - message(FATAL_ERROR "Control Flow Integrity(CFI) sanitizer not available for ${CMAKE_CXX_COMPILER}") - endif () endif() endif() @@ -223,26 +184,17 @@ if(USE_SANITIZER) test_san_flags(SANITIZER_SELECTED_COMPATIBLE ${SANITIZER_SELECTED_FLAGS}) if(SANITIZER_SELECTED_COMPATIBLE) message(STATUS " Building with ${SANITIZER_SELECTED_FLAGS}") - append("${SANITIZER_SELECTED_FLAGS}" CMAKE_C_FLAGS) - if (CMAKE_CXX_COMPILER_LOADED) - append("${SANITIZER_SELECTED_FLAGS}" CMAKE_CXX_FLAGS) - endif () + append("${SANITIZER_SELECTED_FLAGS}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) else() message(FATAL_ERROR "Unsupported value of USE_SANITIZER: ${USE_SANITIZER}") endif() elseif(MSVC) if(USE_SANITIZER MATCHES "([Aa]ddress)") message(STATUS "Building with Address sanitizer") - append("-fsanitize=address" CMAKE_C_FLAGS) - if (CMAKE_CXX_COMPILER_LOADED) - append("-fsanitize=address" CMAKE_CXX_FLAGS) - endif () + append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) if(AFL) - append_quoteless(AFL_USE_ASAN=1 CMAKE_C_COMPILER_LAUNCHER) - if (CMAKE_CXX_COMPILER_LOADED) - append_quoteless(AFL_USE_ASAN=1 CMAKE_CXX_COMPILER_LAUNCHER) - endif () + append_quoteless(AFL_USE_ASAN=1 CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER) endif() else() message(FATAL_ERROR "This sanitizer not yet supported in the MSVC environment: ${USE_SANITIZER}") @@ -253,10 +205,7 @@ if(USE_SANITIZER) elseif(MSVC) if(USE_SANITIZER MATCHES "([Aa]ddress)") message(STATUS "Building with Address sanitizer") - append("/fsanitize=address" CMAKE_C_FLAGS) - if (CMAKE_CXX_COMPILER_LOADED) - append("/fsanitize=address" CMAKE_CXX_FLAGS) - endif () + append("/fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) else() message(FATAL_ERROR "This sanitizer not yet supported in the MSVC environment: ${USE_SANITIZER}") endif() diff --git a/configure.ac b/configure.ac index 502380487e4..3486e80129a 100644 --- a/configure.ac +++ b/configure.ac @@ -1543,7 +1543,7 @@ if test "X$HDF5_DOXYGEN" = "Xyes"; then DOXYGEN_OPTIMIZE_OUTPUT_FOR_C=YES DOXYGEN_MACRO_EXPANSION=YES DOXYGEN_OUTPUT_DIRECTORY=hdf5lib_docs - DOXYGEN_EXAMPLES_DIRECTORY='$(SRCDIR)/doxygen/dox/cookbook $(SRCDIR)/doxygen/examples $(SRCDIR)/src $(SRCDIR)/examples $(SRCDIR)/test' + DOXYGEN_EXAMPLES_DIRECTORY='$(SRCDIR)/doxygen/dox/cookbook $(SRCDIR)/doxygen/examples $(SRCDIR)/src $(SRCDIR)/release_docs $(SRCDIR)/test' DOXYGEN_LAYOUT_FILE='$(SRCDIR)/doxygen/hdf5doxy_layout.xml' DOXYGEN_HTML_HEADER='$(SRCDIR)/doxygen/hdf5_header.html' DOXYGEN_HTML_FOOTER='$(SRCDIR)/doxygen/hdf5_footer.html' @@ -2418,6 +2418,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[int __attribute__((unused)) x]])], AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) +AC_MSG_CHECKING([if compiler supports the __builtin_expect() extension]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[void *ptr = (void*) 0; + if (__builtin_expect (ptr != (void*) 0, 1)) return 0;]])], + [AC_DEFINE([HAVE_BUILTIN_EXPECT], [1], + [Define if supports __builtin_expect() extension]) + AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no])]) + ## ---------------------------------------------------------------------- ## Remove old ways of determining debug/production build. ## These were used in 1.8.x and earlier. We should probably keep these checks @@ -2877,40 +2885,6 @@ if test -n "$DEBUG_PKG_LIST"; then done fi -## ---------------------------------------------------------------------- -## Check if they would like the function stack support compiled in -## -AC_MSG_CHECKING([whether function stack tracking is enabled]) -AC_ARG_ENABLE([codestack], - [AS_HELP_STRING([--enable-codestack], - [Enable the function stack tracing (for developer debugging). - [default=no] - ])], - [CODESTACK=$enableval]) - -## Set the default level. -if test "X-$CODESTACK" = X- ; then - CODESTACK=no -fi - -## Allow this variable to be substituted in -## other files (src/libhdf5.settings.in, etc.) -AC_SUBST([CODESTACK]) - -case "X-$CODESTACK" in - X-yes) - AC_MSG_RESULT([yes]) - AC_DEFINE([HAVE_CODESTACK], [1], - [Define if the function stack tracing code is to be compiled in]) - ;; - X-no) - AC_MSG_RESULT([no]) - ;; - *) - AC_MSG_ERROR([Unrecognized value: $CODESTACK]) - ;; -esac - ## ---------------------------------------------------------------------- ## Enable tracing of the API ## diff --git a/doxygen/CMakeLists.txt b/doxygen/CMakeLists.txt index 7dd7660621d..a3ee438cb8a 100644 --- a/doxygen/CMakeLists.txt +++ b/doxygen/CMakeLists.txt @@ -17,7 +17,7 @@ if (DOXYGEN_FOUND) set (DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES) set (DOXYGEN_MACRO_EXPANSION YES) set (DOXYGEN_OUTPUT_DIRECTORY ${HDF5_BINARY_DIR}/hdf5lib_docs) - set (DOXYGEN_EXAMPLES_DIRECTORY "${HDF5_DOXYGEN_DIR}/dox/cookbook ${HDF5_DOXYGEN_DIR}/examples ${HDF5_SRC_DIR} ${HDF5_SOURCE_DIR}/examples ${HDF5_TEST_SRC_DIR}") + set (DOXYGEN_EXAMPLES_DIRECTORY "${HDF5_DOXYGEN_DIR}/dox/cookbook ${HDF5_DOXYGEN_DIR}/examples ${HDF5_SRC_DIR} ${HDF5_SOURCE_DIR}/release_docs ${HDF5_TEST_SRC_DIR}") set (DOXYGEN_LAYOUT_FILE ${HDF5_DOXYGEN_DIR}/hdf5doxy_layout.xml) set (DOXYGEN_HTML_HEADER ${HDF5_DOXYGEN_DIR}/hdf5_header.html) set (DOXYGEN_HTML_FOOTER ${HDF5_DOXYGEN_DIR}/hdf5_footer.html) diff --git a/doxygen/aliases b/doxygen/aliases index 84c20d5ba24..dd62cb44195 100644 --- a/doxygen/aliases +++ b/doxygen/aliases @@ -387,6 +387,10 @@ ALIASES += str_pad_type="
#H5T_STR_NULLTERM0Null ALIASES += see_virtual=" \see Supporting Functions: H5Pget_layout(), H5Pset_layout(), H5Sget_regular_hyperslab(), H5Sis_regular_hyperslab(), H5Sselect_hyperslab() \see VDS Functions: H5Pget_virtual_count(), H5Pget_virtual_dsetname(), H5Pget_virtual_filename(), H5Pget_virtual_prefix(), H5Pget_virtual_printf_gap(), H5Pget_virtual_srcspace(), H5Pget_virtual_view(), H5Pget_virtual_vspace(), H5Pset_virtual(), H5Pset_virtual_prefix(), H5Pset_virtual_printf_gap(), H5Pset_virtual_view()" ALIASES += obj_info_fields="
FlagPurpose
#H5O_INFO_BASICFill in the fileno, addr, type, and rc fields
#H5O_INFO_TIMEFill in the atime, mtime, ctime, and btime fields
#H5O_INFO_NUM_ATTRS Fill in the num_attrs field
#H5O_INFO_HDRFill in the num_attrs field
#H5O_INFO_META_SIZEFill in the meta_size field
#H5O_INFO_ALL#H5O_INFO_BASIC | #H5O_INFO_TIME | #H5O_INFO_NUM_ATTRS | #H5O_INFO_HDR | #H5O_INFO_META_SIZE
" +ALIASES += details_namelen{2}="Up to \p size characters of the \1 name are returned in \p name; additional characters, if any, are not returned to the user application.\n\n If the length of the \1 name, which determines the required value of \p size, is unknown, a preliminary call to \2() with the last two parameters set to NULL and zero respectively can be made. The return value of this call will be the size in bytes of the \1 name. That value, plus 1 for a NULL terminator, must then be assigned to \p size for a second \2() call, which will retrieve the actual \1 name. +ALIASES += details_namelen_plusone{2}="Up to \p size characters of the \1 name are returned in \p name; additional characters, if any, are not returned to the user application.\n\n If the length of the \1 name, which determines the required value of \p size, is unknown, a preliminary call to \2() with the last two parameters set to NULL and zero respectively can be made. The return value of this call will be the size in bytes of the \1 name plus 1 for a NULL terminator. That value must then be assigned to \p size for a second \2() call, which will retrieve the actual \1 name. + + ################################################################################ # FORTRAN ################################################################################ diff --git a/doxygen/dox/APIVersions.dox b/doxygen/dox/APIVersions.dox index 3658f06d3c7..2ba8bd85205 100644 --- a/doxygen/dox/APIVersions.dox +++ b/doxygen/dox/APIVersions.dox @@ -139,7 +139,7 @@ /** * \ingroup H5R * \def H5Rget_obj_type - * \api_vers_3{H5Rget_obj_type,H5Rget_obj_type1,H5Rget_obj_type2,H5R_get_obj_type3} + * \api_vers_3{H5Rget_obj_type,H5Rget_obj_type1,H5Rget_obj_type2,H5Rget_obj_type3} */ /** diff --git a/doxygen/dox/LearnBasics1.dox b/doxygen/dox/LearnBasics1.dox index d4aa35d8fbb..64ba30ea9bf 100644 --- a/doxygen/dox/LearnBasics1.dox +++ b/doxygen/dox/LearnBasics1.dox @@ -21,6 +21,9 @@ directories and files, an HDF5 object in an HDF5 file is often referred to by it \li /foo/zoo signifies a member of the group foo, which in turn is a member of the root group. +
+Next Chapter \ref LBAPI + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBAPI The HDF5 API @@ -135,6 +138,9 @@ The APIs are listed below:
+
+Previous Chapter \ref LBFileOrg - Next Chapter \ref LBProg + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBProg Programming Issues @@ -203,6 +209,9 @@ Java: Add "import hdf.hdf5lib.H5; +
+Previous Chapter \ref LBAPI - Next Chapter \ref LBFileCreate + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBFileCreate Creating an HDF5 File @@ -395,6 +404,9 @@ The simplified DDL for file definition is as follows: ::= | \endcode +
+Previous Chapter \ref LBProg - Next Chapter \ref LBDsetCreate + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBDsetCreate Creating a Dataset @@ -712,6 +724,9 @@ The following is the simplified DDL dataset definition: \endcode
+ +Previous Chapter \ref LBFileCreate - Next Chapter \ref LBDsetRW + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBDsetRW Reading From and Writing To a Dataset @@ -852,6 +867,8 @@ Shown below is the contents of dsetf.h5 (created by the FORTRAN program). \endcode
+Previous Chapter \ref LBDsetCreate - Next Chapter \ref LBAttrCreate + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBAttrCreate Creating an Attribute @@ -1018,6 +1035,8 @@ ATTRIBUTE "attr" { \endcode
+Previous Chapter \ref LBDsetRW - Next Chapter \ref LBGrpCreate + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics */ diff --git a/doxygen/dox/LearnBasics2.dox b/doxygen/dox/LearnBasics2.dox index 8eda57bc0c2..0df7d9ab620 100644 --- a/doxygen/dox/LearnBasics2.dox +++ b/doxygen/dox/LearnBasics2.dox @@ -63,6 +63,8 @@ GROUP "/" { \endcode
+Previous Chapter \ref LBAttrCreate - Next Chapter \ref LBGrpCreateNames + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBGrpCreateNames Creating Groups using Absolute and Relative Names @@ -189,6 +191,8 @@ GROUP "/" { \endcode
+Previous Chapter \ref LBGrpCreate - Next Chapter \ref LBGrpDset + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBGrpDset Creating Datasets in Groups @@ -298,6 +302,8 @@ DATASET "dset1" { \endcode
+Previous Chapter \ref LBGrpCreateNames - Next Chapter \ref LBDsetSubRW + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBDsetSubRW Reading From or Writing To a Subset of a Dataset @@ -477,6 +483,8 @@ example code. The memory dataspace was defined as one-dimensional. for these parameters, rather than passing in an array for each, and for Fortran 90 you can omit these parameters.
+Previous Chapter \ref LBGrpDset - Next Chapter \ref LBDatatypes + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBDatatypes Datatype Basics @@ -1159,6 +1167,8 @@ If nested VL datatypes were used to create the buffer, this routine frees them f releasing all the memory without creating memory leaks.
+Previous Chapter \ref LBDsetSubRW - Next Chapter \ref LBPropsList + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics */ diff --git a/doxygen/dox/LearnBasics3.dox b/doxygen/dox/LearnBasics3.dox index ce907d4f6a5..ca9ba8bdc4a 100644 --- a/doxygen/dox/LearnBasics3.dox +++ b/doxygen/dox/LearnBasics3.dox @@ -39,6 +39,8 @@ list of the property types. \li Close the property list when done, using #H5Pclose.
+Previous Chapter \ref LBDatatypes - Next Chapter \ref LBDsetLayout + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBDsetLayout Dataset Storage Layout @@ -171,6 +173,8 @@ to a new with a new layout. \see \ref sec_plist in the HDF5 \ref UG.
+Previous Chapter \ref LBPropsList - Next Chapter \ref LBExtDset + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @@ -216,6 +220,8 @@ after this call, the dataset's dataspace must be refreshed with #H5Dget_space be \li Once there is no longer a need for a Property List instance, it should be closed with the #H5Pclose call.
+Previous Chapter \ref LBDsetLayout - Next Chapter \ref LBComDset + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBComDset Compressed Datasets @@ -258,6 +264,8 @@ to #H5Dcreate will fail if attempting to create an SZIP compressed dataset with The conflict can only be detected when the property list is used.
+Previous Chapter \ref LBExtDset - Next Chapter \ref LBContents + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBContents Discovering the Contents of an HDF5 File @@ -302,6 +310,8 @@ The h5ex_g_visit example traverses a file using H5Ovisit and H5Lvisit: \li F90: h5ex_g_visit_F03.f90
+Previous Chapter \ref LBComDset - Next Chapter \ref LBQuiz + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBQuiz Learning the basics QUIZ @@ -398,6 +408,8 @@ is in the root group. How woul
+Previous Chapter \ref LBContents - Next Chapter \ref LBQuizAnswers + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics @page LBQuizAnswers Learning the basics QUIZ with Answers @@ -691,6 +703,8 @@ did = H5Dopen (file_id, "/foo/boo/moo"); /* absolute path */
+Previous Chapter \ref LBQuiz - Next Chapter \ref LBCompiling + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics /** @page LBCompiling Compiling HDF5 Applications @@ -747,6 +761,9 @@ The h5cc, h5c++, and h5fc compile scripts come with the HDF5 binary distribution libraries, and utilities) for the platforms we support. The h5c++ and h5fc utilities are ONLY present if the library was built with C++ and Fortran. +

USING_HDF5_CMake.txt:

+\verbinclude USING_HDF5_CMake.txt + \section secLBCompilingVS Using Visual Studio 1. If you are building on 64-bit Windows, find the "Platform" dropdown @@ -811,7 +828,7 @@ HDF5 C Library \code libhdf5_hl_cpp.a libhdf5_cpp.a -libhdf5hl_fortran.a +libhdf5_hl_fortran.a libhdf5_fortran.a libhdf5_hl.a libhdf5.a @@ -821,7 +838,7 @@ libhdf5.a \code libhdf5_hl_cpp.a libhdf5_cpp.a -libhdf5hl_fortran.a +libhdf5_hl_fortran.a libhdf5_fortran.a libhdf5_hl.a libhdf5.a @@ -832,7 +849,7 @@ libhdf5.a \code libhdf5_hl_cpp.lib libhdf5_cpp.lib -libhdf5hl_fortran.lib +libhdf5_hl_fortran.lib libhdf5_fortran.lib libhdf5_hl.lib libhdf5.lib @@ -863,7 +880,7 @@ HDF5 C Library \code libhdf5_hl_cpp.so libhdf5_cpp.so -libhdf5hl_fortran.so +libhdf5_hl_fortran.so libhdf5_fortran.so libhdf5_hl.so libhdf5.so @@ -873,7 +890,7 @@ libhdf5.so \code libhdf5_hl_cpp.dylib libhdf5_cpp.dylib -libhdf5hl_fortran.dylib +libhdf5_hl_fortran.dylib libhdf5_fortran.dylib libhdf5_hl.dylib libhdf5.dylib @@ -883,7 +900,7 @@ libhdf5.dylib \code hdf5_hl_cpp.lib hdf5_cpp.lib -hdf5hl_fortran.lib +hdf5_hl_fortran.lib hdf5_fortran.lib hdf5_hl.lib hdf5.lib @@ -1001,6 +1018,8 @@ For example, on Unix the log files will be in: There are log files for the configure, test, and build.
+Previous Chapter \ref LBQuizAnswers - Next Chapter \ref LBTraining + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics */ diff --git a/doxygen/dox/TrainingVideos.dox b/doxygen/dox/TrainingVideos.dox index be5f557b683..8e15176f9f4 100644 --- a/doxygen/dox/TrainingVideos.dox +++ b/doxygen/dox/TrainingVideos.dox @@ -40,6 +40,8 @@ Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics
+Previous Chapter \ref LBCompiling + Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics */ diff --git a/doxygen/dox/VOLConnGuide.dox b/doxygen/dox/VOLConnGuide.dox index e30a48428a8..d1b78506fbe 100644 --- a/doxygen/dox/VOLConnGuide.dox +++ b/doxygen/dox/VOLConnGuide.dox @@ -230,7 +230,7 @@ The initialization and terminate callbacks: \endcode \subsection subsecVOLMap Map Storage to HDF5 File Objects -The most difficult part of designing a new VOL connector is going to determining how to support HDF5 +The most difficult part of designing a new VOL connector is determining how to support HDF5 file objects and operations using your storage system. There isn't much specific advice to give here, as each connector will have unique needs, but a forthcoming "tutorial" connector will set up a simple connector and demonstrate this process. diff --git a/doxygen/examples/h5_attribute.c b/doxygen/examples/h5_attribute.c new file mode 100644 index 00000000000..6d3523d5b9e --- /dev/null +++ b/doxygen/examples/h5_attribute.c @@ -0,0 +1,293 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This program illustrates the usage of the H5A Interface functions. + * It creates and writes a dataset, and then creates and writes array, + * scalar, and string attributes of the dataset. + * Program reopens the file, attaches to the scalar attribute using + * attribute name and reads and displays its value. Then index of the + * third attribute is used to read and display attribute values. + * The H5Aiterate function is used to iterate through the dataset attributes, + * and display their names. The function is also reads and displays the values + * of the array attribute. + */ + +#include + +#include "hdf5.h" + +#define H5FILE_NAME "Attributes.h5" + +#define RANK 1 /* Rank and size of the dataset */ +#define SIZE 7 + +#define ARANK 2 /* Rank and dimension sizes of the first dataset attribute */ +#define ADIM1 2 +#define ADIM2 3 +#define ANAME "Float attribute" /* Name of the array attribute */ +#define ANAMES "Character attribute" /* Name of the string attribute */ + +static herr_t attr_info(hid_t loc_id, const char *name, const H5A_info_t *ainfo, void *opdata); +/* Operator function */ + +int +main(void) +{ + + hid_t file, dataset; /* File and dataset identifiers */ + + hid_t fid; /* Dataspace identifier */ + hid_t attr1, attr2, attr3; /* Attribute identifiers */ + hid_t attr; + hid_t aid1, aid2, aid3; /* Attribute dataspace identifiers */ + hid_t atype, atype_mem; /* Attribute type */ + H5T_class_t type_class; + + hsize_t fdim[] = {SIZE}; + hsize_t adim[] = {ADIM1, ADIM2}; /* Dimensions of the first attribute */ + + float matrix[ADIM1][ADIM2]; /* Attribute data */ + + herr_t ret; /* Return value */ + H5O_info2_t oinfo; /* Object info */ + unsigned i, j; /* Counters */ + char string_out[80]; /* Buffer to read string attribute back */ + int point_out; /* Buffer to read scalar attribute back */ + + /* + * Data initialization. + */ + int vector[] = {1, 2, 3, 4, 5, 6, 7}; /* Dataset data */ + int point = 1; /* Value of the scalar attribute */ + char string[] = "ABCD"; /* Value of the string attribute */ + + for (i = 0; i < ADIM1; i++) { /* Values of the array attribute */ + for (j = 0; j < ADIM2; j++) + matrix[i][j] = -1.; + } + + /* + * Create a file. + */ + file = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Create the dataspace for the dataset in the file. + */ + fid = H5Screate(H5S_SIMPLE); + ret = H5Sset_extent_simple(fid, RANK, fdim, NULL); + + /* + * Create the dataset in the file. + */ + dataset = H5Dcreate2(file, "Dataset", H5T_NATIVE_INT, fid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Write data to the dataset. + */ + ret = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, vector); + + /* + * Create dataspace for the first attribute. + */ + aid1 = H5Screate(H5S_SIMPLE); + ret = H5Sset_extent_simple(aid1, ARANK, adim, NULL); + + /* + * Create array attribute. + */ + attr1 = H5Acreate2(dataset, ANAME, H5T_NATIVE_FLOAT, aid1, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Write array attribute. + */ + ret = H5Awrite(attr1, H5T_NATIVE_FLOAT, matrix); + + /* + * Create scalar attribute. + */ + aid2 = H5Screate(H5S_SCALAR); + attr2 = H5Acreate2(dataset, "Integer attribute", H5T_NATIVE_INT, aid2, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Write scalar attribute. + */ + ret = H5Awrite(attr2, H5T_NATIVE_INT, &point); + + /* + * Create string attribute. + */ + aid3 = H5Screate(H5S_SCALAR); + atype = H5Tcopy(H5T_C_S1); + H5Tset_size(atype, 5); + H5Tset_strpad(atype, H5T_STR_NULLTERM); + attr3 = H5Acreate2(dataset, ANAMES, atype, aid3, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Write string attribute. + */ + ret = H5Awrite(attr3, atype, string); + + /* + * Close attribute and file dataspaces, and datatype. + */ + ret = H5Sclose(aid1); + ret = H5Sclose(aid2); + ret = H5Sclose(aid3); + ret = H5Sclose(fid); + ret = H5Tclose(atype); + + /* + * Close the attributes. + */ + ret = H5Aclose(attr1); + ret = H5Aclose(attr2); + ret = H5Aclose(attr3); + + /* + * Close the dataset. + */ + ret = H5Dclose(dataset); + + /* + * Close the file. + */ + ret = H5Fclose(file); + + /* + * Reopen the file. + */ + file = H5Fopen(H5FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT); + + /* + * Open the dataset. + */ + dataset = H5Dopen2(file, "Dataset", H5P_DEFAULT); + + /* + * Attach to the scalar attribute using attribute name, then read and + * display its value. + */ + attr = H5Aopen(dataset, "Integer attribute", H5P_DEFAULT); + ret = H5Aread(attr, H5T_NATIVE_INT, &point_out); + printf("The value of the attribute \"Integer attribute\" is %d \n", point_out); + ret = H5Aclose(attr); + + //! [H5Oget_info3_snip] + + /* + * Find string attribute by iterating through all attributes + */ + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + for (i = 0; i < (unsigned)oinfo.num_attrs; i++) { + attr = H5Aopen_by_idx(dataset, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)i, H5P_DEFAULT, + H5P_DEFAULT); + atype = H5Aget_type(attr); + type_class = H5Tget_class(atype); + if (type_class == H5T_STRING) { + atype_mem = H5Tget_native_type(atype, H5T_DIR_ASCEND); + ret = H5Aread(attr, atype_mem, string_out); + printf("Found string attribute; its index is %d , value = %s \n", i, string_out); + ret = H5Tclose(atype_mem); + } + ret = H5Aclose(attr); + ret = H5Tclose(atype); + } + + //! [H5Oget_info3_snip] + /* + * Get attribute info using iteration function. + */ + ret = H5Aiterate2(dataset, H5_INDEX_NAME, H5_ITER_INC, NULL, attr_info, NULL); + + /* + * Close the dataset and the file. + */ + H5Dclose(dataset); + H5Fclose(file); + + return 0; +} + +/* + * Operator function. + */ +static herr_t +attr_info(hid_t loc_id, const char *name, const H5A_info_t *ainfo, void *opdata) +{ + hid_t attr, atype, aspace; /* Attribute, datatype and dataspace identifiers */ + int rank; + hsize_t sdim[64]; + herr_t ret; + int i; + size_t npoints; /* Number of elements in the array attribute. */ + float *float_array; /* Pointer to the array attribute. */ + + /* avoid warnings */ + (void)opdata; + + /* + * Open the attribute using its name. + */ + attr = H5Aopen(loc_id, name, H5P_DEFAULT); + + /* + * Display attribute name. + */ + printf("\nName : %s\n", name); + + /* + * Get attribute datatype, dataspace, rank, and dimensions. + */ + atype = H5Aget_type(attr); + aspace = H5Aget_space(attr); + rank = H5Sget_simple_extent_ndims(aspace); + ret = H5Sget_simple_extent_dims(aspace, sdim, NULL); + + /* + * Display rank and dimension sizes for the array attribute. + */ + + if (rank > 0) { + printf("Rank : %d \n", rank); + printf("Dimension sizes : "); + for (i = 0; i < rank; i++) + printf("%d ", (int)sdim[i]); + printf("\n"); + } + + /* + * Read array attribute and display its type and values. + */ + + if (H5T_FLOAT == H5Tget_class(atype)) { + printf("Type : FLOAT \n"); + npoints = H5Sget_simple_extent_npoints(aspace); + float_array = (float *)malloc(sizeof(float) * (int)npoints); + ret = H5Aread(attr, atype, float_array); + printf("Values : "); + for (i = 0; i < (int)npoints; i++) + printf("%f ", float_array[i]); + printf("\n"); + free(float_array); + } + + /* + * Release all identifiers. + */ + H5Tclose(atype); + H5Sclose(aspace); + H5Aclose(attr); + + return 0; +} diff --git a/doxygen/examples/h5_extlink.c b/doxygen/examples/h5_extlink.c new file mode 100644 index 00000000000..e1f02cf4cfd --- /dev/null +++ b/doxygen/examples/h5_extlink.c @@ -0,0 +1,662 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* This program demonstrates how to create and use "external links" in + * HDF5. + * + * External links point from one HDF5 file to an object (Group, Dataset, or + * committed Datatype) in another file. + */ + +#include "hdf5.h" +#include + +#define SOURCE_FILE "extlink_source.h5" +#define TARGET_FILE "extlink_target.h5" + +#define PREFIX_SOURCE_FILE "extlink_prefix_source.h5" + +#define SOFT_LINK_FILE "soft_link.h5" +#define SOFT_LINK_NAME "soft_link_to_group" +#define UD_SOFT_LINK_NAME "ud_soft_link" +#define TARGET_GROUP "target_group" + +#define UD_SOFT_CLASS 65 + +#define HARD_LINK_FILE "hard_link.h5" +#define HARD_LINK_NAME "hard_link_to_group" +#define UD_HARD_LINK_NAME "ud_hard_link" + +#define UD_HARD_CLASS 66 + +#define PLIST_LINK_PROP "plist_link_prop" +#define UD_PLIST_CLASS 66 + +/* Basic external link example + * + * Creates two files and uses an external link to access an object in the + * second file from the first file. + */ +static void +extlink_example(void) +{ + hid_t source_file_id, targ_file_id; + hid_t group_id, group2_id; + + /* Create two files, a source and a target */ + source_file_id = H5Fcreate(SOURCE_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + targ_file_id = H5Fcreate(TARGET_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create a group in the target file for the external link to point to. */ + group_id = H5Gcreate2(targ_file_id, "target_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* Close the group and the target file */ + H5Gclose(group_id); + + /* Create an external link in the source file pointing to the target group. + * We could instead have created the external link first, then created the + * group it points to; the order doesn't matter. + */ + H5Lcreate_external(TARGET_FILE, "target_group", source_file_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT); + + /* Now we can use the external link to create a new group inside the + * target group (even though the target file is closed!). The external + * link works just like a soft link. + */ + group_id = H5Gcreate2(source_file_id, "ext_link/new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* The group is inside the target file and we can access it normally. + * Here, group_id and group2_id point to the same group inside the + * target file. + */ + group2_id = H5Gopen2(targ_file_id, "target_group/new_group", H5P_DEFAULT); + + /* Don't forget to close the IDs we opened. */ + H5Gclose(group2_id); + H5Gclose(group_id); + + H5Fclose(targ_file_id); + H5Fclose(source_file_id); + + /* The link from the source file to the target file will work as long as + * the target file can be found. If the target file is moved, renamed, + * or deleted in the filesystem, HDF5 won't be able to find it and the + * external link will "dangle." + */ +} + +/* External link prefix example + * + * Uses a group access property list to set a "prefix" for the filenames + * accessed through an external link. + * + * Group access property lists inherit from link access property lists; + * the external link prefix property is actually a property of LAPLs. + * + * This example requires a "red" directory and a "blue" directory to exist + * where it is run (so to run this example on Unix, first mkdir red and mkdir + * blue). + */ +static void +extlink_prefix_example(void) +{ + hid_t source_file_id, red_file_id, blue_file_id; + hid_t group_id, group2_id; + hid_t gapl_id; + + /* Create three files, a source and two targets. The targets will have + * the same name, but one will be located in the red directory and one will + * be located in the blue directory */ + source_file_id = H5Fcreate(PREFIX_SOURCE_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + red_file_id = H5Fcreate("red/prefix_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + blue_file_id = H5Fcreate("blue/prefix_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* This test needs a red and a blue directory in the filesystem. If they're not present, + * trying to create the files above will fail. + */ + if (red_file_id < 0 || blue_file_id < 0) + printf("This test requires directories named 'red' and 'blue' to exist. Did you forget to create " + "them?\n"); + + /* Create an external link in the source file pointing to the root group of + * a file named prefix_target.h5. This file doesn't exist in the current + * directory, but the files in the red and blue directories both have this + * name. + */ + H5Lcreate_external("prefix_target.h5", "/", source_file_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT); + + /* If we tried to traverse the external link now, we would fail (since the + * file it points to doesn't exist). Instead, we'll create a group access + * property list that will provide a prefix path to the external link. + * Group access property lists inherit the properties of link access + * property lists. + */ + gapl_id = H5Pcreate(H5P_GROUP_ACCESS); + H5Pset_elink_prefix(gapl_id, "red/"); + + /* Now if we traverse the external link, HDF5 will look for an external + * file named red/prefix_target.h5, which exists. + * To pass the group access property list, we need to use H5Gopen2. + */ + group_id = H5Gopen2(source_file_id, "ext_link", gapl_id); + + /* Now we can use the open group ID to create a new group inside the + * "red" file. + */ + group2_id = H5Gcreate2(group_id, "pink", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* Close both groups. */ + H5Gclose(group2_id); + H5Gclose(group_id); + + /* If we change the prefix, the same external link can find a file in the blue + * directory. + */ + H5Pset_elink_prefix(gapl_id, "blue/"); + group_id = H5Gopen2(source_file_id, "ext_link", gapl_id); + group2_id = H5Gcreate2(group_id, "sky blue", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* Close both groups. */ + H5Gclose(group2_id); + H5Gclose(group_id); + + /* Each file has had a group created inside it using the same external link. */ + group_id = H5Gopen2(red_file_id, "pink", H5P_DEFAULT); + group2_id = H5Gopen2(blue_file_id, "sky blue", H5P_DEFAULT); + + /* Clean up our open IDs */ + H5Gclose(group2_id); + H5Gclose(group_id); + H5Pclose(gapl_id); + H5Fclose(blue_file_id); + H5Fclose(red_file_id); + H5Fclose(source_file_id); + + /* User-defined links can expand on the ability to pass in parameters + * using an access property list; for instance, a user-defined link + * might function like an external link but allow the full filename to be + * passed in through the access property list. + */ +} + +/* Soft Link example + * + * Create a new class of user-defined links that behave like HDF5's built-in + * soft links. + * + * This isn't very useful by itself (HDF5's soft links already do the same + * thing), but it can serve as an example for how to reference objects by + * name. + */ + +/* We need to define the callback function that the soft link will use. + * It is defined after the example below. + * To keep the example simple, these links don't have a query callback. + * In general, link classes should always be query-able. + * We might also have wanted to supply a creation callback that checks + * that a path was supplied in the udata. + */ +static hid_t UD_soft_traverse(const char *link_name, hid_t cur_group, const void *udata, size_t udata_size, + hid_t lapl_id, hid_t dxpl_id); + +static void +soft_link_example(void) +{ + hid_t file_id; + hid_t group_id; + /* Define the link class that we'll use to register "user-defined soft + * links" using the callbacks we defined above. + * A link class can have NULL for any callback except its traverse + * callback. + */ + const H5L_class_t UD_soft_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* Version number for this struct. + * This field is always H5L_LINK_CLASS_T_VERS */ + (H5L_type_t)UD_SOFT_CLASS, /* Link class id number. This can be any + * value between H5L_TYPE_UD_MIN (64) and + * H5L_TYPE_MAX (255). It should be a + * value that isn't already being used by + * another kind of link. We'll use 65. */ + "UD_soft_link", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move callback */ + NULL, /* Copy callback */ + UD_soft_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ + }}; + + /* First, create a file and an object within the file for the link to + * point to. + */ + file_id = H5Fcreate(SOFT_LINK_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + group_id = H5Gcreate2(file_id, TARGET_GROUP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + H5Gclose(group_id); + + /* This is how we create a normal soft link to the group. + */ + H5Lcreate_soft(TARGET_GROUP, file_id, SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT); + + /* To do the same thing using a user-defined link, we first have to + * register the link class we defined. + */ + H5Lregister(UD_soft_class); + + /* Now create a user-defined link. We give it the path to the group + * as its udata.1 + */ + H5Lcreate_ud(file_id, UD_SOFT_LINK_NAME, (H5L_type_t)UD_SOFT_CLASS, TARGET_GROUP, + strlen(TARGET_GROUP) + 1, H5P_DEFAULT, H5P_DEFAULT); + + /* We can access the group through the UD soft link like we would through + * a normal soft link. This link will still dangle if the object's + * original name is changed or unlinked. + */ + group_id = H5Gopen2(file_id, UD_SOFT_LINK_NAME, H5P_DEFAULT); + + /* The group is now open normally. Don't forget to close it! */ + H5Gclose(group_id); + + H5Fclose(file_id); +} + +/* UD_soft_traverse + * The actual traversal function simply needs to open the correct object by + * name and return its ID. + */ + +static hid_t +UD_soft_traverse(const char *link_name, hid_t cur_group, const void *udata, size_t udata_size, hid_t lapl_id, + hid_t dxpl_id) +{ + const char *target = (const char *)udata; + hid_t ret_value; + + /* Pass the udata straight through to HDF5. If it's invalid, let HDF5 + * return an error. + */ + ret_value = H5Oopen(cur_group, target, lapl_id); + return ret_value; +} + +/* Hard Link example + * + * Create a new class of user-defined links that behave like HDF5's built-in + * hard links. + * + * This isn't very useful by itself (HDF5's hard links already do the same + * thing), but it can serve as an example for how to reference objects by + * address. + */ + +/* We need to define the callback functions that the hard link will use. + * These are defined after the example below. + * To keep the example simple, these links don't have a query callback. + * Generally, real link classes should always be query-able. + */ +static herr_t UD_hard_create(const char *link_name, hid_t loc_group, const void *udata, size_t udata_size, + hid_t lcpl_id); +static herr_t UD_hard_delete(const char *link_name, hid_t loc_group, const void *udata, size_t udata_size); +static hid_t UD_hard_traverse(const char *link_name, hid_t cur_group, const void *udata, size_t udata_size, + hid_t lapl_id, hid_t dxpl_id); + +static void +hard_link_example(void) +{ + hid_t file_id; + hid_t group_id; + H5L_info2_t li; + /* Define the link class that we'll use to register "user-defined hard + * links" using the callbacks we defined above. + * A link class can have NULL for any callback except its traverse + * callback. + */ + const H5L_class_t UD_hard_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* Version number for this struct. + * This field is always H5L_LINK_CLASS_T_VERS */ + (H5L_type_t)UD_HARD_CLASS, /* Link class id number. This can be any + * value between H5L_TYPE_UD_MIN (64) and + * H5L_TYPE_MAX (255). It should be a + * value that isn't already being used by + * another kind of link. We'll use 66. */ + "UD_hard_link", /* Link class name for debugging */ + UD_hard_create, /* Creation callback */ + NULL, /* Move callback */ + NULL, /* Copy callback */ + UD_hard_traverse, /* The actual traversal function */ + UD_hard_delete, /* Deletion callback */ + NULL /* Query callback */ + }}; + + /* First, create a file and an object within the file for the link to + * point to. + */ + file_id = H5Fcreate(HARD_LINK_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + group_id = H5Gcreate2(file_id, TARGET_GROUP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + H5Gclose(group_id); + + /* This is how we create a normal hard link to the group. This + * creates a second "name" for the group. + */ + H5Lcreate_hard(file_id, TARGET_GROUP, file_id, HARD_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT); + + /* To do the same thing using a user-defined link, we first have to + * register the link class we defined. + */ + H5Lregister(UD_hard_class); + + /* Since hard links link by object address, we'll need to retrieve + * the target group's address. We do this by calling H5Lget_info + * on a hard link to the object. + */ + H5Lget_info2(file_id, TARGET_GROUP, &li, H5P_DEFAULT); + + /* Now create a user-defined link. We give it the group's address + * as its udata. + */ + H5Lcreate_ud(file_id, UD_HARD_LINK_NAME, (H5L_type_t)UD_HARD_CLASS, &(li.u.token), sizeof(H5O_token_t), + H5P_DEFAULT, H5P_DEFAULT); + + /* The UD hard link has now incremented the group's reference count + * like a normal hard link would. This means that we can unlink the + * other two links to that group and it won't be deleted until the + * UD hard link is deleted. + */ + H5Ldelete(file_id, TARGET_GROUP, H5P_DEFAULT); + H5Ldelete(file_id, HARD_LINK_NAME, H5P_DEFAULT); + + /* The group is still accessible through the UD hard link. If this were + * a soft link instead, the object would have been deleted when the last + * hard link to it was unlinked. */ + group_id = H5Gopen2(file_id, UD_HARD_LINK_NAME, H5P_DEFAULT); + + /* The group is now open normally. Don't forget to close it! */ + H5Gclose(group_id); + + /* Removing the user-defined hard link will delete the group. */ + H5Ldelete(file_id, UD_HARD_LINK_NAME, H5P_DEFAULT); + + H5Fclose(file_id); +} + +/* Callbacks for User-defined hard links. */ +/* UD_hard_create + * The most important thing this callback does is to increment the reference + * count on the target object. Without this step, the object could be + * deleted while this link still pointed to it, resulting in possible data + * corruption! + * The create callback also checks the arguments used to create this link. + * If this function returns a negative value, the call to H5Lcreate_ud() + * will also return failure and the link will not be created. + */ +static herr_t +UD_hard_create(const char *link_name, hid_t loc_group, const void *udata, size_t udata_size, hid_t lcpl_id) +{ + H5O_token_t token; + hid_t target_obj = H5I_INVALID_HID; + herr_t ret_value = 0; + + /* Make sure that the address passed in looks valid */ + if (udata_size != sizeof(H5O_token_t)) { + ret_value = -1; + goto done; + } + + token = *((const H5O_token_t *)udata); + + //! [H5Oopen_by_token_snip] + + /* Open the object this link points to so that we can increment + * its reference count. This also ensures that the token passed + * in points to a real object (although this check is not perfect!) */ + target_obj = H5Oopen_by_token(loc_group, token); + + //! [H5Oopen_by_token_snip] + + if (target_obj < 0) { + ret_value = -1; + goto done; + } + + /* Increment the reference count of the target object */ + if (H5Oincr_refcount(target_obj) < 0) { + ret_value = -1; + goto done; + } + +done: + /* Close the target object if we opened it */ + if (target_obj >= 0) + H5Oclose(target_obj); + return ret_value; +} + +/* UD_hard_delete + * Since the creation function increments the object's reference count, it's + * important to decrement it again when the link is deleted. + */ +static herr_t +UD_hard_delete(const char *link_name, hid_t loc_group, const void *udata, size_t udata_size) +{ + H5O_token_t token; + hid_t target_obj = H5I_INVALID_HID; + herr_t ret_value = 0; + + /* Sanity check; we have already verified the udata's size in the creation + * callback. + */ + if (udata_size != sizeof(H5O_token_t)) { + ret_value = -1; + goto done; + } + + token = *((const H5O_token_t *)udata); + + /* Open the object this link points to */ + target_obj = H5Oopen_by_token(loc_group, token); + if (target_obj < 0) { + ret_value = -1; + goto done; + } + + /* Decrement the reference count of the target object */ + if (H5Odecr_refcount(target_obj) < 0) { + ret_value = -1; + goto done; + } + +done: + /* Close the target object if we opened it */ + if (target_obj >= 0) + H5Oclose(target_obj); + return ret_value; +} + +/* UD_hard_traverse + * The actual traversal function simply needs to open the correct object and + * return its ID. + */ +static hid_t +UD_hard_traverse(const char *link_name, hid_t cur_group, const void *udata, size_t udata_size, hid_t lapl_id, + hid_t dxpl_id) +{ + H5O_token_t token; + hid_t ret_value = H5I_INVALID_HID; + + /* Sanity check; we have already verified the udata's size in the creation + * callback. + */ + if (udata_size != sizeof(H5O_token_t)) + return H5I_INVALID_HID; + + token = *((const H5O_token_t *)udata); + + /* Open the object by token. If H5Oopen_by_token fails, ret_value will + * be negative to indicate that the traversal function failed. + */ + ret_value = H5Oopen_by_token(cur_group, token); + + return ret_value; +} + +/* Plist example + * + * Create a new class of user-defined links that open objects within a file + * based on a value passed in through a link access property list. + * + * Group, dataset, and datatype access property lists all inherit from link + * access property lists, so they can be used instead of LAPLs. + */ + +/* We need to define the callback functions that this link type will use. + * These are defined after the example below. + * These links have no udata, so they don't need a query function. + */ +static hid_t UD_plist_traverse(const char *link_name, hid_t cur_group, const void *udata, size_t udata_size, + hid_t lapl_id, hid_t dxpl_id); + +static void +plist_link_example(void) +{ + hid_t file_id; + hid_t group_id, group2_id; + hid_t gapl_id; + char *path = NULL; + + /* Define the link class that we'll use to register "plist + * links" using the callback we defined above. + * A link class can have NULL for any callback except its traverse + * callback. + */ + const H5L_class_t UD_plist_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* Version number for this struct. + * This field is always H5L_LINK_CLASS_T_VERS */ + (H5L_type_t)UD_PLIST_CLASS, /* Link class id number. This can be any + * value between H5L_TYPE_UD_MIN (64) and + * H5L_TYPE_MAX (255). It should be a + * value that isn't already being used by + * another kind of link. We'll use 67. */ + "UD_plist_link", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move callback */ + NULL, /* Copy callback */ + UD_plist_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ + }}; + + /* First, create a file and two objects within the file for the link to + * point to. + */ + file_id = H5Fcreate(HARD_LINK_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + group_id = H5Gcreate2(file_id, "group_1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + H5Gclose(group_id); + group_id = H5Gcreate2(file_id, "group_1/group_2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + H5Gclose(group_id); + + /* Register "plist links" and create one. It has no udata at all. */ + H5Lregister(UD_plist_class); + H5Lcreate_ud(file_id, "plist_link", (H5L_type_t)UD_PLIST_CLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT); + + /* Create a group access property list to pass in the target for the + * plist link. + */ + gapl_id = H5Pcreate(H5P_GROUP_ACCESS); + + /* There is no HDF5 API for setting the property that controls these + * links, so we have to add the property manually + */ + H5Pinsert2(gapl_id, PLIST_LINK_PROP, sizeof(const char *), &(path), NULL, NULL, NULL, NULL, NULL, NULL); + + /* Set the property to point to the first group. */ + path = "group_1"; + H5Pset(gapl_id, PLIST_LINK_PROP, &path); + + /* Open the first group through the plist link using the GAPL we just + * created */ + group_id = H5Gopen2(file_id, "plist_link", gapl_id); + + /* If we change the value set on the property list, it will change where + * the plist link points. + */ + path = "group_1/group_2"; + H5Pset(gapl_id, PLIST_LINK_PROP, &path); + group2_id = H5Gopen2(file_id, "plist_link", gapl_id); + + /* group_id points to group_1 and group2_id points to group_2, both opened + * through the same link. + * Using more than one of this type of link could quickly become confusing, + * since they will all use the same property list; however, there is + * nothing to prevent the links from changing the property list in their + * traverse callbacks. + */ + + /* Clean up */ + H5Pclose(gapl_id); + H5Gclose(group_id); + H5Gclose(group2_id); + H5Fclose(file_id); +} + +/* Traversal callback for User-defined plist links. */ +/* UD_plist_traverse + * Open a path passed in through the property list. + */ +static hid_t +UD_plist_traverse(const char *link_name, hid_t cur_group, const void *udata, size_t udata_size, hid_t lapl_id, + hid_t dxpl_id) +{ + char *path; + hid_t ret_value = H5I_INVALID_HID; + + /* If the link property isn't set or can't be found, traversal fails. */ + if (H5Pexist(lapl_id, PLIST_LINK_PROP) < 0) + goto error; + + if (H5Pget(lapl_id, PLIST_LINK_PROP, &path) < 0) + goto error; + + /* Open the object by address. If H5Oopen_by_addr fails, ret_value will + * be negative to indicate that the traversal function failed. + */ + ret_value = H5Oopen(cur_group, path, lapl_id); + + return ret_value; + +error: + return H5I_INVALID_HID; +} + +/* Main function + * + * Invokes the example functions. + */ +int +main(void) +{ + printf("Testing basic external links.\n"); + extlink_example(); + + printf("Testing external link prefixes.\n"); + extlink_prefix_example(); + + printf("Testing user-defined soft links.\n"); + soft_link_example(); + + printf("Testing user-defined hard links.\n"); + hard_link_example(); + + printf("Testing user-defined property list links.\n"); + plist_link_example(); + + return 0; +} diff --git a/doxygen/examples/tables/volAPIs.dox b/doxygen/examples/tables/volAPIs.dox index 6b9df9b8f08..88299960ea6 100644 --- a/doxygen/examples/tables/volAPIs.dox +++ b/doxygen/examples/tables/volAPIs.dox @@ -320,7 +320,7 @@ deprecated -#H5Ovisit by name1 +#H5Ovisit_by_name1 deprecated @@ -328,7 +328,7 @@ deprecated -#H5Ovisit by name2 +#H5Ovisit_by_name2 deprecated diff --git a/fortran/src/H5Rff.F90 b/fortran/src/H5Rff.F90 index ea7cbb69c9b..ab803a7596a 100644 --- a/fortran/src/H5Rff.F90 +++ b/fortran/src/H5Rff.F90 @@ -1,4 +1,3 @@ -!> @defgroup FH5R Fortran References (H5R) Interface !! !! @see H5R, C-API !! @@ -48,6 +47,8 @@ MODULE H5R USE H5GLOBAL + USE H5fortkit + IMPLICIT NONE ! If you change the value of these parameters, do not forget to change corresponding @@ -66,7 +67,7 @@ MODULE H5R PRIVATE h5rget_object_type_obj_f PRIVATE h5rget_region_region_f, h5rget_region_ptr_f - PRIVATE h5rcreate_object_f, h5rcreate_region_f, h5rcreate_ptr_f + PRIVATE h5rcreate_object_deprec_f, h5rcreate_region_deprec_f, h5rcreate_ptr_f PRIVATE h5rdereference_object_f, h5rdereference_region_f, h5rdereference_ptr_f PRIVATE h5rget_name_object_f, h5rget_name_region_f, h5rget_name_ptr_f @@ -75,6 +76,10 @@ MODULE H5R INTEGER(C_SIGNED_CHAR), DIMENSION(1:H5R_DSET_REG_REF_BUF_SIZE_F) :: ref END TYPE hdset_reg_ref_t_f03 + TYPE, BIND(C) :: H5R_ref_t + INTEGER(C_INT8_T), DIMENSION(1:H5R_REF_BUF_SIZE_F) :: data + END TYPE + INTERFACE h5rget_object_type_f MODULE PROCEDURE h5rget_object_type_obj_f END INTERFACE @@ -87,9 +92,9 @@ MODULE H5R END INTERFACE INTERFACE h5rcreate_f - MODULE PROCEDURE h5rcreate_ptr_f ! F2003 - MODULE PROCEDURE h5rcreate_object_f ! obsolete - MODULE PROCEDURE h5rcreate_region_f ! obsolete + MODULE PROCEDURE h5rcreate_ptr_f ! F2003 + MODULE PROCEDURE h5rcreate_object_deprec_f ! obsolete + MODULE PROCEDURE h5rcreate_region_deprec_f ! obsolete END INTERFACE INTERFACE h5rdereference_f @@ -294,7 +299,7 @@ END SUBROUTINE h5rget_region_ptr_f !! !! See C API: @ref H5Rcreate_object() !! - SUBROUTINE h5rcreate_object_f(loc_id, name, ref, hdferr) + SUBROUTINE h5rcreate_object_deprec_f(loc_id, name, ref, hdferr) USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: loc_id @@ -310,7 +315,7 @@ SUBROUTINE h5rcreate_object_f(loc_id, name, ref, hdferr) hdferr = h5rcreate_ptr_c(f_ptr, loc_id, name, namelen, INT(0), INT(-1,HID_T)) - END SUBROUTINE h5rcreate_object_f + END SUBROUTINE h5rcreate_object_deprec_f !> !! \ingroup FH5R @@ -327,7 +332,7 @@ END SUBROUTINE h5rcreate_object_f !! !! See C API: @ref H5Rcreate_region() !! - SUBROUTINE h5rcreate_region_f(loc_id, name, space_id, ref, hdferr) + SUBROUTINE h5rcreate_region_deprec_f(loc_id, name, space_id, ref, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: loc_id CHARACTER(LEN=*), INTENT(IN) :: name @@ -355,7 +360,7 @@ END FUNCTION h5rcreate_region_c hdferr = h5rcreate_region_c(ref_f, loc_id, name, namelen, space_id ) ref%ref = ref_f - END SUBROUTINE h5rcreate_region_f + END SUBROUTINE h5rcreate_region_deprec_f !> !! \ingroup FH5R @@ -639,5 +644,604 @@ END FUNCTION h5rget_obj_type_c hdferr = h5rget_obj_type_c(loc_id, ref_type, ref, obj_type) END SUBROUTINE h5rget_obj_type_f +!> +!! \ingroup FH5R +!! +!! \brief Opens the HDF5 object referenced. +!! +!! \param ref_ptr Pointer to reference to open, points object of TYPE(H5R_ref_t) +!! \param obj_id Object identifier +!! \param hdferr \fortran_error +!! \param rapl_id Reference access property list identifier +!! \param oapl_id Object access property list identifier +!! +!! See C API: @ref H5Ropen_object() +!! + SUBROUTINE h5ropen_object_f(ref_ptr, obj_id, hdferr, rapl_id, oapl_id) + + IMPLICIT NONE + + TYPE(C_PTR) :: ref_ptr + INTEGER(HID_T) , INTENT(OUT) :: obj_id + INTEGER , INTENT(OUT) :: hdferr + INTEGER(HID_T), OPTIONAL, INTENT(IN) :: rapl_id + INTEGER(HID_T), OPTIONAL, INTENT(IN) :: oapl_id + + INTEGER(HID_T) :: rapl_id_default + INTEGER(HID_T) :: oapl_id_default + + INTERFACE + INTEGER(HID_T) FUNCTION H5Ropen_object(ref_ptr, rapl_id, oapl_id) & + BIND(C, NAME='H5Ropen_object') + IMPORT :: C_PTR + IMPORT :: HID_T + IMPLICIT NONE + TYPE(C_PTR) , VALUE :: ref_ptr + INTEGER(HID_T), VALUE :: rapl_id + INTEGER(HID_T), VALUE :: oapl_id + END FUNCTION H5Ropen_object + END INTERFACE + + rapl_id_default = H5P_DEFAULT_F + IF(PRESENT(rapl_id)) rapl_id_default = rapl_id + oapl_id_default = H5P_DEFAULT_F + IF(PRESENT(oapl_id)) oapl_id_default = oapl_id + + obj_id = H5Ropen_object(ref_ptr, rapl_id_default, oapl_id_default) + + hdferr = 0 + IF(obj_id.LT.0) hdferr = -1 + + END SUBROUTINE h5ropen_object_f +!> +!! \ingroup FH5R +!! +!! \brief Opens the HDF5 attribute referenced. +!! +!! \param ref_ptr Pointer to reference to open, points object of TYPE(H5R_ref_t) +!! \param obj_id Object identifier +!! \param hdferr \fortran_error +!! \param rapl_id Reference access property list identifier +!! \param aapl_id Attribute access property list identifier +!! +!! See C API: @ref H5Ropen_attr() +!! + SUBROUTINE h5ropen_attr_f(ref_ptr, obj_id, hdferr, rapl_id, aapl_id) + + IMPLICIT NONE + + TYPE(C_PTR) :: ref_ptr + INTEGER(HID_T) , INTENT(OUT) :: obj_id + INTEGER , INTENT(OUT) :: hdferr + INTEGER(HID_T), OPTIONAL, INTENT(IN) :: rapl_id + INTEGER(HID_T), OPTIONAL, INTENT(IN) :: aapl_id + + INTEGER(HID_T) :: rapl_id_default + INTEGER(HID_T) :: aapl_id_default + + INTERFACE + INTEGER(HID_T) FUNCTION H5Ropen_attr(ref_ptr, rapl_id, aapl_id) & + BIND(C, NAME='H5Ropen_attr') + IMPORT :: C_PTR + IMPORT :: HID_T + IMPLICIT NONE + TYPE(C_PTR) , VALUE :: ref_ptr + INTEGER(HID_T), VALUE :: rapl_id + INTEGER(HID_T), VALUE :: aapl_id + END FUNCTION H5Ropen_attr + END INTERFACE + + rapl_id_default = H5P_DEFAULT_F + IF(PRESENT(rapl_id)) rapl_id_default = rapl_id + aapl_id_default = H5P_DEFAULT_F + IF(PRESENT(aapl_id)) aapl_id_default = aapl_id + + obj_id = H5Ropen_attr(ref_ptr, rapl_id_default, aapl_id_default) + + hdferr = 0 + IF(obj_id.LT.0) hdferr = -1 + + END SUBROUTINE h5ropen_attr_f +!> +!! \ingroup FH5R +!! +!! \brief Sets up a dataspace and selection as specified by a region reference. +!! +!! \param ref_ptr Pointer to reference to open, points object of TYPE(H5R_ref_t) +!! \param space_id Dataspace identifier +!! \param hdferr \fortran_error +!! \param rapl_id Reference access property list identifier +!! \param oapl_id Object access property list identifier +!! +!! See C API: @ref H5Ropen_region() +!! + SUBROUTINE h5ropen_region_f(ref_ptr, space_id, hdferr, rapl_id, oapl_id) + + IMPLICIT NONE + + TYPE(C_PTR) :: ref_ptr + INTEGER(HID_T) , INTENT(OUT) :: space_id + INTEGER , INTENT(OUT) :: hdferr + INTEGER(HID_T), OPTIONAL, INTENT(IN) :: rapl_id + INTEGER(HID_T), OPTIONAL, INTENT(IN) :: oapl_id + + INTEGER(HID_T) :: rapl_id_default + INTEGER(HID_T) :: oapl_id_default + + INTERFACE + INTEGER(HID_T) FUNCTION H5Ropen_region(ref_ptr, rapl_id, oapl_id) & + BIND(C, NAME='H5Ropen_region') + IMPORT :: C_PTR + IMPORT :: HID_T + IMPLICIT NONE + TYPE(C_PTR) , VALUE :: ref_ptr + INTEGER(HID_T), VALUE :: rapl_id + INTEGER(HID_T), VALUE :: oapl_id + END FUNCTION H5Ropen_region + END INTERFACE + + rapl_id_default = H5P_DEFAULT_F + IF(PRESENT(rapl_id)) rapl_id_default = rapl_id + oapl_id_default = H5P_DEFAULT_F + IF(PRESENT(oapl_id)) oapl_id_default = oapl_id + + space_id = H5Ropen_region(ref_ptr, rapl_id_default, oapl_id_default) + + hdferr = 0 + IF(space_id.LT.0) hdferr = -1 + + END SUBROUTINE h5ropen_region_f +!> +!! \ingroup FH5R +!! +!! \brief Copies an existing reference. +!! +!! \param src_ref_ptr Pointer to reference to copy, of TYPE(H5R_ref_t) +!! \param dst_ref_ptr Pointer to output reference, of TYPE(H5R_ref_t) +!! \param hdferr \fortran_error +!! +!! See C API: @ref H5Rcopy() +!! + SUBROUTINE h5rcopy_f(src_ref_ptr, dst_ref_ptr, hdferr) + + IMPLICIT NONE + + TYPE(C_PTR) :: src_ref_ptr + TYPE(C_PTR) :: dst_ref_ptr + INTEGER, INTENT(OUT) :: hdferr + + INTERFACE + INTEGER(C_INT) FUNCTION H5Rcopy(src_ref_ptr, dst_ref_ptr) & + BIND(C, NAME='H5Rcopy') + IMPORT :: C_PTR, C_INT + IMPLICIT NONE + TYPE(C_PTR), VALUE :: src_ref_ptr + TYPE(C_PTR), VALUE :: dst_ref_ptr + END FUNCTION H5Rcopy + END INTERFACE + + hdferr = INT(H5Rcopy(src_ref_ptr, dst_ref_ptr)) + + END SUBROUTINE h5rcopy_f +!> +!! \ingroup FH5R +!! +!! \brief Determines whether two references are equal +!! +!! \param ref1_ptr Pointer to reference to compare, of TYPE(H5R_ref_t) +!! \param ref2_ptr Pointer to reference to compare, of TYPE(H5R_ref_t) +!! \param equal If reference are equal +!! \param hdferr \fortran_error +!! +!! See C API: @ref H5Requal() +!! + SUBROUTINE h5requal_f(ref1_ptr, ref2_ptr, equal, hdferr) + + IMPLICIT NONE + + TYPE(C_PTR) :: ref1_ptr + TYPE(C_PTR) :: ref2_ptr + LOGICAL, INTENT(OUT) :: equal + INTEGER, INTENT(OUT) :: hdferr + + INTEGER(C_INT) :: c_equal + + INTERFACE + INTEGER(C_INT) FUNCTION H5Requal(ref1_ptr, ref2_ptr) & + BIND(C, NAME='H5Requal') + IMPORT :: C_PTR, C_INT + IMPLICIT NONE + TYPE(C_PTR), VALUE :: ref1_ptr + TYPE(C_PTR), VALUE :: ref2_ptr + END FUNCTION H5Requal + END INTERFACE + + c_equal = INT(H5Requal(ref1_ptr, ref2_ptr)) + + hdferr = 0 + equal = .FALSE. + IF(c_equal .EQ. 1)THEN + equal = .TRUE. + ELSE IF(c_equal .LT. 0)THEN + hdferr = -1 + ENDIF + + END SUBROUTINE h5requal_f + +!> +!! \ingroup FH5R +!! +!! \brief Retrieves the type of a reference. +!! +!! \param ref_ptr Pointer to reference to copy, of TYPE(H5R_ref_t) +!! \param ref_type A reference type +!! \param hdferr \fortran_error +!! +!! See C API: @ref H5Rget_type() +!! + SUBROUTINE h5rget_type_f(ref_ptr, ref_type, hdferr) + + IMPLICIT NONE + + TYPE(C_PTR) :: ref_ptr + INTEGER, INTENT(OUT) :: ref_type + INTEGER, INTENT(OUT) :: hdferr + + INTERFACE + INTEGER(C_INT) FUNCTION H5Rget_type(ref_ptr) & + BIND(C, NAME='H5Rget_type') + IMPORT :: C_PTR, C_INT + IMPLICIT NONE + TYPE(C_PTR), VALUE :: ref_ptr + END FUNCTION H5Rget_type + END INTERFACE + + ref_type = INT(H5Rget_type(ref_ptr)) + + hdferr = 0 + IF(ref_type .EQ. H5R_BADTYPE_F) hdferr = -1 + + END SUBROUTINE h5rget_type_f + +!> +!! \ingroup FH5R +!! +!! \brief Closes a reference. +!! +!! \param ref_ptr Pointer to reference, of TYPE(H5R_ref_t) +!! \param hdferr \fortran_error +!! +!! See C API: @ref H5Rdestroy() +!! + SUBROUTINE h5rdestroy_f(ref_ptr, hdferr) + + IMPLICIT NONE + + TYPE(C_PTR) :: ref_ptr + INTEGER, INTENT(OUT) :: hdferr + + INTERFACE + INTEGER(C_INT) FUNCTION H5Rdestroy(ref_ptr) & + BIND(C, NAME='H5Rdestroy') + IMPORT :: C_PTR, C_INT + IMPLICIT NONE + TYPE(C_PTR), VALUE :: ref_ptr + END FUNCTION H5Rdestroy + END INTERFACE + + hdferr = INT(H5Rdestroy(ref_ptr)) + + END SUBROUTINE h5rdestroy_f + +!> +!! \ingroup FH5R +!! +!! \brief Creates a reference. +!! +!! \attention \fortran_approved +!! +!! \param loc_id Location identifier. +!! \param name Name of the dataset at the specified location +!! \param ref Reference created by the function call +!! \param hdferr \fortran_error +!! \param oapl_id Object access property list identifier +!! +!! See C API: @ref H5Rcreate_object() +!! + SUBROUTINE h5rcreate_object_f(loc_id, name, ref, hdferr, oapl_id) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR + IMPLICIT NONE + INTEGER(HID_T) , INTENT(IN) :: loc_id + CHARACTER(LEN=*), INTENT(IN) :: name + TYPE(C_PTR) :: ref + INTEGER , INTENT(OUT) :: hdferr + INTEGER(HID_T), INTENT(IN), OPTIONAL :: oapl_id + + INTEGER(HID_T) :: oapl_id_default + CHARACTER(LEN=LEN_TRIM(name)+1,KIND=C_CHAR) :: c_name + + INTERFACE + INTEGER(C_INT) FUNCTION H5Rcreate_object(loc_id, c_name, oapl_id_default, ref) & + BIND(C, NAME='H5Rcreate_object') + IMPORT :: C_PTR, C_INT, C_CHAR + IMPORT :: HID_T + IMPLICIT NONE + INTEGER(HID_T), VALUE :: loc_id + CHARACTER(KIND=C_CHAR), DIMENSION(*) :: c_name + INTEGER(HID_T), VALUE :: oapl_id_default + TYPE(C_PTR), VALUE :: ref + END FUNCTION H5Rcreate_object + END INTERFACE + + c_name = TRIM(name)//C_NULL_CHAR + + oapl_id_default = H5P_DEFAULT_F + IF(PRESENT(oapl_id)) oapl_id_default = oapl_id + + hdferr = INT(H5Rcreate_object(loc_id, c_name, oapl_id_default, ref)) + + END SUBROUTINE h5rcreate_object_f +!> +!! \ingroup FH5R +!! +!! \brief Creates a region reference. +!! +!! \attention \fortran_approved +!! +!! \param loc_id Location identifier +!! \param name Name of object +!! \param space_id Dataspace identifier +!! \param ref_ptr Pointer to reference +!! \param hdferr \fortran_error +!! \param oapl_id Object access property list identifier +!! +!! See C API: @ref H5Rcreate_region() +!! + SUBROUTINE h5rcreate_region_f(loc_id, name, space_id, ref_ptr, hdferr, oapl_id) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR + IMPLICIT NONE + INTEGER(HID_T) , INTENT(IN) :: loc_id + CHARACTER(LEN=*), INTENT(IN) :: name + INTEGER(HID_T) , INTENT(IN) :: space_id + TYPE(C_PTR) :: ref_ptr + INTEGER , INTENT(OUT) :: hdferr + INTEGER(HID_T) , INTENT(IN), OPTIONAL :: oapl_id + + INTEGER(HID_T) :: oapl_id_default + CHARACTER(LEN=LEN_TRIM(name)+1,KIND=C_CHAR) :: c_name + + INTERFACE + INTEGER(C_INT) FUNCTION H5Rcreate_region(loc_id, c_name, space_id, oapl_id_default, ref_ptr) & + BIND(C, NAME='H5Rcreate_region') + IMPORT :: C_PTR, C_INT, C_CHAR + IMPORT :: HID_T + IMPLICIT NONE + INTEGER(HID_T), VALUE :: loc_id + CHARACTER(KIND=C_CHAR), DIMENSION(*) :: c_name + INTEGER(HID_T), VALUE :: space_id + INTEGER(HID_T), VALUE :: oapl_id_default + TYPE(C_PTR), VALUE :: ref_ptr + END FUNCTION H5Rcreate_region + END INTERFACE + + c_name = TRIM(name)//C_NULL_CHAR + + oapl_id_default = H5P_DEFAULT_F + IF(PRESENT(oapl_id)) oapl_id_default = oapl_id + + hdferr = INT(H5Rcreate_region(loc_id, c_name, space_id, oapl_id_default, ref_ptr)) + + END SUBROUTINE h5rcreate_region_f +!> +!! \ingroup FH5R +!! +!! \brief Creates an attribute reference. +!! +!! \attention \fortran_approved +!! +!! \param loc_id Location identifier +!! \param name Name of object +!! \param attr_name Name of attribute +!! \param ref_ptr Pointer to reference +!! \param hdferr \fortran_error +!! \param oapl_id Object access property list identifier +!! +!! See C API: @ref H5Rcreate_attr() +!! + SUBROUTINE h5rcreate_attr_f(loc_id, name, attr_name, ref_ptr, hdferr, oapl_id) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR + IMPLICIT NONE + INTEGER(HID_T) , INTENT(IN) :: loc_id + CHARACTER(LEN=*), INTENT(IN) :: name + CHARACTER(LEN=*), INTENT(IN) :: attr_name + TYPE(C_PTR) :: ref_ptr + INTEGER , INTENT(OUT) :: hdferr + INTEGER(HID_T) , INTENT(IN), OPTIONAL :: oapl_id + + INTEGER(HID_T) :: oapl_id_default + CHARACTER(LEN=LEN_TRIM(name)+1,KIND=C_CHAR) :: c_name + CHARACTER(LEN=LEN_TRIM(attr_name)+1,KIND=C_CHAR) :: c_attr_name + + INTERFACE + INTEGER(C_INT) FUNCTION H5Rcreate_attr(loc_id, c_name, c_attr_name, oapl_id_default, ref_ptr) & + BIND(C, NAME='H5Rcreate_attr') + IMPORT :: C_PTR, C_INT, C_CHAR + IMPORT :: HID_T + IMPLICIT NONE + INTEGER(HID_T), VALUE :: loc_id + CHARACTER(KIND=C_CHAR), DIMENSION(*) :: c_name + CHARACTER(KIND=C_CHAR), DIMENSION(*) :: c_attr_name + INTEGER(HID_T), VALUE :: oapl_id_default + TYPE(C_PTR), VALUE :: ref_ptr + END FUNCTION H5Rcreate_attr + END INTERFACE + + c_name = TRIM(name)//C_NULL_CHAR + c_attr_name = TRIM(attr_name)//C_NULL_CHAR + + oapl_id_default = H5P_DEFAULT_F + IF(PRESENT(oapl_id)) oapl_id_default = oapl_id + + hdferr = INT(H5Rcreate_attr(loc_id, c_name, c_attr_name, oapl_id_default, ref_ptr)) + + END SUBROUTINE h5rcreate_attr_f +!> +!! \ingroup FH5R +!! +!! \brief Retrieves the object name for a referenced object. +!! +!! \param ref_ptr Pointer to reference to query +!! \param name Buffer to place the file name of the reference +!! \param hdferr \fortran_error +!! \param rapl_id Reference access property list identifier +!! \param name_len Maximum length of the name to retrieve +!! + SUBROUTINE h5rget_obj_name_f( ref_ptr, name, hdferr, rapl_id, name_len) + + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR + IMPLICIT NONE + TYPE(C_PTR) :: ref_ptr + CHARACTER(LEN=*) :: name + INTEGER , INTENT(OUT) :: hdferr + INTEGER(SIZE_T), INTENT(OUT), OPTIONAL :: name_len + INTEGER(HID_T) , INTENT(IN) , OPTIONAL :: rapl_id + + CHARACTER(LEN=1,KIND=C_CHAR), DIMENSION(1:LEN(name)+1), TARGET :: c_name + INTEGER(HID_T) :: rapl_id_default + INTEGER(SIZE_T) :: l + + INTERFACE + INTEGER(SIZE_T) FUNCTION H5Rget_obj_name(ref_ptr, rapl_id, name, size_default) & + BIND(C, NAME='H5Rget_obj_name') + IMPORT :: c_char, c_ptr + IMPORT :: HID_T, SIZE_T + IMPLICIT NONE + TYPE(C_PTR), VALUE :: ref_ptr + INTEGER(HID_T), VALUE :: rapl_id + CHARACTER(KIND=C_CHAR), DIMENSION(*) :: name + INTEGER(SIZE_T), VALUE :: size_default + END FUNCTION H5Rget_obj_name + END INTERFACE + + rapl_id_default = H5P_DEFAULT_F + IF(PRESENT(rapl_id)) rapl_id_default = rapl_id + + hdferr = 0 + IF(PRESENT(name_len))THEN + c_name(1:1)(1:1) = C_NULL_CHAR + name_len = H5Rget_obj_name(ref_ptr, rapl_id_default, c_name, 1_SIZE_T) + IF(name_len.LT.0_SIZE_T) hdferr = H5I_INVALID_HID_F + ELSE + l = INT(LEN(name)+1,SIZE_T) + IF(H5Rget_obj_name(ref_ptr, rapl_id_default, c_name, l) .LT. 0_SIZE_T)THEN + hdferr = H5I_INVALID_HID_F + ELSE + CALL HD5c2fstring(name, c_name, LEN(name,KIND=SIZE_T), LEN(name,KIND=SIZE_T)+1_SIZE_T ) + ENDIF + ENDIF + + END SUBROUTINE h5rget_obj_name_f +!> +!! \ingroup FH5R +!! +!! \brief Retrieves the attribute name for a referenced object. +!! +!! \param ref_ptr Pointer to reference to query +!! \param name Buffer to place the attribute name of the reference +!! \param hdferr \fortran_error +!! \param name_len Maximum length of the name to retrieve +!! + SUBROUTINE h5rget_attr_name_f(ref_ptr, name, hdferr, name_len) + + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR + IMPLICIT NONE + TYPE(C_PTR) :: ref_ptr + CHARACTER(LEN=*) :: name + INTEGER , INTENT(OUT) :: hdferr + INTEGER(SIZE_T), INTENT(OUT), OPTIONAL :: name_len + + CHARACTER(LEN=1,KIND=C_CHAR), DIMENSION(1:LEN(name)+1), TARGET :: c_name + INTEGER(SIZE_T) :: l + + INTERFACE + INTEGER(SIZE_T) FUNCTION H5Rget_attr_name(ref_ptr, name, size_default) & + BIND(C, NAME='H5Rget_attr_name') + IMPORT :: c_char, c_ptr + IMPORT :: HID_T, SIZE_T + IMPLICIT NONE + TYPE(C_PTR), VALUE :: ref_ptr + CHARACTER(KIND=C_CHAR), DIMENSION(*) :: name + INTEGER(SIZE_T), VALUE :: size_default + END FUNCTION H5Rget_attr_name + END INTERFACE + + hdferr = 0 + IF(PRESENT(name_len))THEN + c_name(1:1)(1:1) = C_NULL_CHAR + name_len = H5Rget_attr_name(ref_ptr, c_name, 1_SIZE_T) + IF(name_len.LT.0_SIZE_T) hdferr = H5I_INVALID_HID_F + ! Don't include the NULL term in the size + name_len = name_len - 1 + ELSE + l = INT(LEN(name)+1,SIZE_T) + IF(H5Rget_attr_name(ref_ptr, c_name, l) .LT. 0_SIZE_T)THEN + hdferr = H5I_INVALID_HID_F + ELSE + CALL HD5c2fstring(name, c_name, LEN(name,KIND=SIZE_T), LEN(name,KIND=SIZE_T)+1_SIZE_T ) + ENDIF + ENDIF + + END SUBROUTINE h5rget_attr_name_f +!> +!! \ingroup FH5R +!! +!! \brief Retrieves the file name for a referenced object. +!! +!! \param ref_ptr Pointer to reference to query +!! \param name Buffer to place the file name of the reference +!! \param hdferr \fortran_error +!! \param name_len The size of the name buffer +!! +!! See C API: @ref H5Rget_file_name() +!! + SUBROUTINE h5rget_file_name_f(ref_ptr, name, hdferr, name_len) + + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR + IMPLICIT NONE + TYPE(C_PTR) :: ref_ptr + CHARACTER(LEN=*) :: name + INTEGER , INTENT(OUT) :: hdferr + INTEGER(SIZE_T), INTENT(OUT), OPTIONAL :: name_len + + CHARACTER(LEN=1,KIND=C_CHAR), DIMENSION(1:LEN(name)+1), TARGET :: c_name + INTEGER(SIZE_T) :: l + + INTERFACE + INTEGER(SIZE_T) FUNCTION H5Rget_file_name(ref_ptr, name, size_default) & + BIND(C, NAME='H5Rget_file_name') + IMPORT :: c_char, c_ptr + IMPORT :: HID_T, SIZE_T + IMPLICIT NONE + TYPE(C_PTR), VALUE :: ref_ptr + CHARACTER(KIND=C_CHAR), DIMENSION(*) :: name + INTEGER(SIZE_T), VALUE :: size_default + END FUNCTION H5Rget_file_name + END INTERFACE + + hdferr = 0 + IF(PRESENT(name_len))THEN + c_name(1:1)(1:1) = C_NULL_CHAR + name_len = H5Rget_file_name(ref_ptr, c_name, 1_SIZE_T) + IF(name_len.LT.0_SIZE_T) hdferr = H5I_INVALID_HID_F + ELSE + l = INT(LEN(name)+1,SIZE_T) + IF(H5Rget_file_name(ref_ptr, c_name, l) .LT. 0_SIZE_T)THEN + hdferr = H5I_INVALID_HID_F + ELSE + CALL HD5c2fstring(name, c_name, LEN(name,KIND=SIZE_T), LEN(name,KIND=SIZE_T)+1_SIZE_T ) + ENDIF + ENDIF + + END SUBROUTINE h5rget_file_name_f END MODULE H5R diff --git a/fortran/src/H5Sff.F90 b/fortran/src/H5Sff.F90 index 5f2f1d260ad..3c301c2f462 100644 --- a/fortran/src/H5Sff.F90 +++ b/fortran/src/H5Sff.F90 @@ -312,7 +312,7 @@ END SUBROUTINE h5sget_select_elem_npoints_f !! \brief Gets the list of element points currently selected. !! !! \param space_id Dataspace identifier. -!! \param startpoint Element point to start with. +!! \param startpoint Element point to start with, \Bold{0-based indices}. !! \param num_points Number of element points to get. !! \param buf Buffer with element points selected. !! \param hdferr \fortran_error diff --git a/fortran/src/H5_f.c b/fortran/src/H5_f.c index e6f7b6d01a4..530068ba880 100644 --- a/fortran/src/H5_f.c +++ b/fortran/src/H5_f.c @@ -298,7 +298,8 @@ h5init_types_c(hid_t_f *types, hid_t_f *floatingtypes, hid_t_f *integertypes) return ret_value; if ((integertypes[26] = (hid_t_f)H5Tcopy(H5T_C_S1)) < 0) return ret_value; - + if ((integertypes[27] = (hid_t_f)H5Tcopy(H5T_STD_REF)) < 0) + return ret_value; /* * Define Fortran H5T_STRING type to store non-fixed size strings */ @@ -766,6 +767,13 @@ h5init_flags_c(int_f *h5d_flags, size_t_f *h5d_size_flags, int_f *h5e_flags, hid */ h5r_flags[0] = (int_f)H5R_OBJECT; h5r_flags[1] = (int_f)H5R_DATASET_REGION; + h5r_flags[2] = (int_f)H5R_BADTYPE; + h5r_flags[3] = (int_f)H5R_OBJECT1; + h5r_flags[4] = (int_f)H5R_DATASET_REGION1; + h5r_flags[5] = (int_f)H5R_OBJECT2; + h5r_flags[6] = (int_f)H5R_DATASET_REGION2; + h5r_flags[7] = (int_f)H5R_ATTR; + h5r_flags[8] = (int_f)H5R_MAXTYPE; /* * H5S flags diff --git a/fortran/src/H5_ff.F90 b/fortran/src/H5_ff.F90 index e83768a1dfd..fb3bba67198 100644 --- a/fortran/src/H5_ff.F90 +++ b/fortran/src/H5_ff.F90 @@ -130,7 +130,7 @@ MODULE H5LIB ! ! H5R flags declaration ! - INTEGER, PARAMETER :: H5R_FLAGS_LEN = 2 + INTEGER, PARAMETER :: H5R_FLAGS_LEN = 9 INTEGER, DIMENSION(1:H5R_FLAGS_LEN) :: H5R_flags ! ! H5S flags declaration @@ -319,6 +319,7 @@ END FUNCTION h5init1_flags_c H5T_STD_B64LE = integer_types(25) H5T_FORTRAN_S1 = integer_types(26) H5T_C_S1 = integer_types(27) + H5T_STD_REF = integer_types(28) error = error + h5init_flags_c(H5D_flags, & H5D_size_flags, & @@ -627,8 +628,15 @@ END FUNCTION h5init1_flags_c ! ! H5R flags ! - H5R_OBJECT_F = H5R_flags(1) - H5R_DATASET_REGION_F = H5R_flags(2) + H5R_OBJECT_F = H5R_flags(1) + H5R_DATASET_REGION_F = H5R_flags(2) + H5R_BADTYPE_F = H5R_flags(3) + H5R_OBJECT1_F = H5R_flags(4) + H5R_DATASET_REGION1_F = H5R_flags(5) + H5R_OBJECT2_F = H5R_flags(6) + H5R_DATASET_REGION2_F = H5R_flags(7) + H5R_ATTR_F = H5R_flags(8) + H5R_MAXTYPE_F = H5R_flags(9) ! ! H5S flags ! diff --git a/fortran/src/H5f90global.F90 b/fortran/src/H5f90global.F90 index 5b4fc648587..4794bdc83c8 100644 --- a/fortran/src/H5f90global.F90 +++ b/fortran/src/H5f90global.F90 @@ -45,6 +45,7 @@ MODULE H5GLOBAL ! values in the H5f90.h file. INTEGER, PARAMETER :: REF_REG_BUF_LEN = 3 INTEGER, PARAMETER :: H5O_TOKEN_BUF_LEN = 16 ! Matches C defined value in H5public.h + INTEGER, PARAMETER :: H5R_REF_BUF_SIZE_F = 64 ! Matches C defined value in H5public.h !> \addtogroup FH5R !> @{ @@ -63,7 +64,7 @@ MODULE H5GLOBAL ! datatypes are added INTEGER, PARAMETER :: PREDEF_TYPES_LEN = 19 INTEGER, PARAMETER :: FLOATING_TYPES_LEN = 4 - INTEGER, PARAMETER :: INTEGER_TYPES_LEN = 27 + INTEGER, PARAMETER :: INTEGER_TYPES_LEN = 28 ! These arrays need to be global because they are used in ! both h5open_f and in h5close_f; initialize to fix linking issues @@ -119,6 +120,7 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5T_C_S1 !DEC$ATTRIBUTES DLLEXPORT :: H5T_NATIVE_INTEGER_KIND !DEC$ATTRIBUTES DLLEXPORT :: H5T_NATIVE_FLOAT_128 + !DEC$ATTRIBUTES DLLEXPORT :: H5T_STD_REF !DEC$endif !> \addtogroup FH5T !> @{ @@ -165,7 +167,8 @@ MODULE H5GLOBAL INTEGER(HID_T) :: H5T_NATIVE_B32 !< H5T_NATIVE_B32 INTEGER(HID_T) :: H5T_NATIVE_B64 !< H5T_NATIVE_B64 INTEGER(HID_T) :: H5T_FORTRAN_S1 !< H5T_FORTRAN_S1 - INTEGER(HID_T) :: H5T_C_S1 !< H5T_C_S1 + INTEGER(HID_T) :: H5T_C_S1 !< H5T_C_S1 + INTEGER(HID_T) :: H5T_STD_REF !< H5T_STD_REF #ifndef H5_DOXYGEN INTEGER, PARAMETER :: NUM_NATIVE_INTEGER_KIND = 5 @@ -761,11 +764,25 @@ MODULE H5GLOBAL !DEC$if defined(BUILD_HDF5_DLL) !DEC$ATTRIBUTES DLLEXPORT :: H5R_OBJECT_F !DEC$ATTRIBUTES DLLEXPORT :: H5R_DATASET_REGION_F + !DEC$ATTRIBUTES DLLEXPORT :: H5R_BADTYPE_F + !DEC$ATTRIBUTES DLLEXPORT :: H5R_OBJECT1_F + !DEC$ATTRIBUTES DLLEXPORT :: H5R_DATASET_REGION1_F + !DEC$ATTRIBUTES DLLEXPORT :: H5R_OBJECT2_F + !DEC$ATTRIBUTES DLLEXPORT :: H5R_DATASET_REGION2_F + !DEC$ATTRIBUTES DLLEXPORT :: H5R_ATTR_F + !DEC$ATTRIBUTES DLLEXPORT :: H5R_MAXTYPE_F !DEC$endif !> \addtogroup FH5R !> @{ - INTEGER :: H5R_OBJECT_F !< H5R_OBJECT - INTEGER :: H5R_DATASET_REGION_F !< H5R_DATASET_REGION + INTEGER :: H5R_OBJECT_F !< H5R_OBJECT + INTEGER :: H5R_DATASET_REGION_F !< H5R_DATASET_REGION + INTEGER :: H5R_BADTYPE_F !< H5R_BADTYPE + INTEGER :: H5R_OBJECT1_F !< H5R_OBJECT1 + INTEGER :: H5R_DATASET_REGION1_F !< H5R_DATASET_REGION1 + INTEGER :: H5R_OBJECT2_F !< H5R_OBJECT2 + INTEGER :: H5R_DATASET_REGION2_F !< H5R_DATASET_REGION2 + INTEGER :: H5R_ATTR_F !< H5R_ATTR + INTEGER :: H5R_MAXTYPE_F !< H5R_MAXTYPE !> @} ! ! H5S flags declaration diff --git a/fortran/src/hdf5_fortrandll.def.in b/fortran/src/hdf5_fortrandll.def.in index 56f54acbf75..ae5465f73a2 100644 --- a/fortran/src/hdf5_fortrandll.def.in +++ b/fortran/src/hdf5_fortrandll.def.in @@ -458,8 +458,11 @@ H5P_mp_H5PGET_ACTUAL_SELECTION_IO_MODE_F @H5_NOPAREXP@H5P_mp_H5PGET_COLL_METADATA_WRITE_F @H5_NOPAREXP@H5P_mp_H5PGET_MPIO_NO_COLLECTIVE_CAUSE_F ; H5R +H5R_mp_H5RCREATE_OBJECT_DEPREC_F +H5R_mp_H5RCREATE_REGION_DEPREC_F H5R_mp_H5RCREATE_OBJECT_F H5R_mp_H5RCREATE_REGION_F +H5R_mp_H5RCREATE_ATTR_F H5R_mp_H5RDEREFERENCE_OBJECT_F H5R_mp_H5RDEREFERENCE_REGION_F H5R_mp_H5RGET_REGION_REGION_F @@ -471,6 +474,16 @@ H5R_mp_H5RCREATE_PTR_F H5R_mp_H5RDEREFERENCE_PTR_F H5R_mp_H5RGET_NAME_PTR_F H5R_mp_H5RGET_OBJ_TYPE_F +H5R_mp_H5ROPEN_ATTR_F +H5R_mp_H5ROPEN_OBJECT_F +H5R_mp_H5ROPEN_REGION_F +H5R_mp_H5RCOPY_F +H5R_mp_H5RGET_FILE_NAME_F +H5R_mp_H5RGET_ATTR_NAME_F +H5R_mp_H5RGET_OBJ_NAME_F +H5R_mp_H5REQUAL_F +H5R_mp_H5RDESTROY_F +H5R_mp_H5RGET_TYPE_F ; H5S H5S_mp_H5SCREATE_SIMPLE_F H5S_mp_H5SCLOSE_F diff --git a/fortran/test/fortranlib_test.F90 b/fortran/test/fortranlib_test.F90 index 05ae593bfd6..534bde6c9a0 100644 --- a/fortran/test/fortranlib_test.F90 +++ b/fortran/test/fortranlib_test.F90 @@ -141,6 +141,10 @@ PROGRAM fortranlibtest ! 'Testing REFERENCE Interface ' ! '=========================================' + ret_total_error = 0 + CALL v3reftest(cleanup, ret_total_error) + CALL write_test_status(ret_total_error, ' Version 3 references test', total_error) + ret_total_error = 0 CALL refobjtest(cleanup, ret_total_error) CALL write_test_status(ret_total_error, ' Reference to object test', total_error) @@ -149,6 +153,7 @@ PROGRAM fortranlibtest CALL refregtest(cleanup, ret_total_error) CALL write_test_status(ret_total_error, ' Reference to dataset region test', total_error) + ! ! '=========================================' ! 'Testing selection functionalities ' diff --git a/fortran/test/tH5R.F90 b/fortran/test/tH5R.F90 index 7c5a374c295..8eb8d8d2f9a 100644 --- a/fortran/test/tH5R.F90 +++ b/fortran/test/tH5R.F90 @@ -28,6 +28,9 @@ ! !***** ! + +#include + MODULE TH5R USE HDF5 @@ -69,7 +72,7 @@ SUBROUTINE refobjtest(cleanup, total_error) INTEGER(HSIZE_T), DIMENSION(2) :: data_dims CHARACTER(LEN=7) :: buf ! buffer to hold the region name - CHARACTER(LEN=16) :: buf_big ! buffer bigger then needed + CHARACTER(LEN=16) :: buf_big ! buffer bigger than needed INTEGER(SIZE_T) :: buf_size ! returned size of the region buffer name ! @@ -162,10 +165,10 @@ SUBROUTINE refobjtest(cleanup, total_error) CALL check("H5Rget_name_f", error, total_error) - CALL verify("H5Rget_name_f", INT(buf_size),7, total_error) + CALL VERIFY("H5Rget_name_f", INT(buf_size),LEN("/"//groupname1), total_error) CALL verify("H5Rget_name_f", buf, "/GROUP1", total_error) - ! with buffer bigger then needed + ! with a buffer bigger than needed CALL H5Rget_name_f(dsetr_id, ref(1), buf_big, error, buf_size ) CALL check("H5Rget_name_f", error, total_error) @@ -252,8 +255,8 @@ SUBROUTINE refregtest(cleanup, total_error) CHARACTER(LEN=17), PARAMETER :: dsetnamer = "REGION_REFERENCES" CHARACTER(LEN=7) :: buf ! buffer to hold the region name - CHARACTER(LEN=11) :: buf_big ! buffer bigger then needed - CHARACTER(LEN=4) :: buf_small ! buffer smaller then needed + CHARACTER(LEN=11) :: buf_big ! buffer bigger than needed + CHARACTER(LEN=4) :: buf_small ! buffer smaller than needed INTEGER(SIZE_T) :: buf_size ! returned size of the region buffer name INTEGER(HID_T) :: file_id ! File identifier INTEGER(HID_T) :: space_id ! Dataspace identifier @@ -406,7 +409,7 @@ SUBROUTINE refregtest(cleanup, total_error) CALL verify("H5Rget_name_f", buf, "/MATRIX", total_error) ! Get name of the dataset the first region reference points to using H5Rget_name_f - ! buffer bigger then needed + ! buffer bigger than needed CALL H5Rget_name_f(dsetr_id, ref_out(1), buf_big, error, buf_size ) CALL check("H5Rget_name_f", error, total_error) CALL verify("H5Rget_name_f", INT(buf_size),7,total_error) @@ -414,7 +417,7 @@ SUBROUTINE refregtest(cleanup, total_error) ! Get name of the dataset the first region reference points to using H5Rget_name_f - ! buffer smaller then needed + ! buffer smaller than needed CALL H5Rget_name_f(dsetr_id, ref_out(1), buf_small, error, buf_size ) CALL check("H5Rget_name_f", error, total_error) CALL verify("H5Rget_name_f", INT(buf_size),7,total_error) @@ -470,11 +473,386 @@ SUBROUTINE refregtest(cleanup, total_error) CALL h5fclose_f(file_id, error) CALL check("h5fclose_f", error, total_error) - IF(cleanup) CALL h5_cleanup_f(filename, H5P_DEFAULT_F, error) CALL check("h5_cleanup_f", error, total_error) RETURN END SUBROUTINE refregtest +SUBROUTINE v3reftest(cleanup, total_error) + IMPLICIT NONE + LOGICAL, INTENT(IN) :: cleanup + INTEGER, INTENT(INOUT) :: total_error + + CHARACTER(LEN=11), PARAMETER :: filename = "v3reference" + CHARACTER(LEN=8) , PARAMETER :: dsetnamei = "INTEGERS" + CHARACTER(LEN=17), PARAMETER :: dsetnamer = "OBJECT_REFERENCES" + CHARACTER(LEN=6) , PARAMETER :: groupname1 = "GROUP1" + CHARACTER(LEN=6) , PARAMETER :: groupname2 = "GROUP2" + CHARACTER(LEN=5) , PARAMETER :: attrname = "ATTR1" + INTEGER , PARAMETER :: ref_size = 6 + INTEGER , PARAMETER :: arr_size = 5 + INTEGER , PARAMETER :: rank = 1 + INTEGER , PARAMETER :: datawrite_size = 2 + + CHARACTER(LEN=80) :: fix_filename + INTEGER(HID_T) :: file_id ! File identifier + INTEGER(HID_T) :: grp1_id ! Group identifier + INTEGER(HID_T) :: grp2_id ! Group identifier + INTEGER(HID_T) :: dset1_id ! Dataset identifier + INTEGER(HID_T) :: dsetr_id ! Dataset identifier + INTEGER(HID_T) :: type_id ! Type identifier + INTEGER(HID_T) :: space_id ! Dataspace identifier + INTEGER(HID_T) :: spacer_id ! Dataspace identifier + INTEGER(HID_T) :: sid, sid2, aid, aid2, dspace_id, dspace_id1 + INTEGER :: error, ref_type + INTEGER(HSIZE_T), DIMENSION(1) :: dims = (/arr_size/) + INTEGER(HSIZE_T), DIMENSION(1) :: dimsr= (/ref_size/) + INTEGER :: i + TYPE(H5R_ref_t), DIMENSION(ref_size), TARGET :: ref_ptr + TYPE(H5R_ref_t), DIMENSION(ref_size), TARGET :: ref_ptr_read + TYPE(H5R_ref_t), TARGET :: ref_ptr_cp + INTEGER, DIMENSION(arr_size), TARGET :: DATA = (/1, 2, 3, 4, 5/) + INTEGER, DIMENSION(2), TARGET :: data_write = (/100, 500/) + INTEGER(HSIZE_T), DIMENSION(rank) :: dimspt = (/datawrite_size/) + INTEGER(HSIZE_T), DIMENSION(1:2) :: coord + +#ifdef H5_FORTRAN_HAVE_CHAR_ALLOC + CHARACTER(:), ALLOCATABLE :: buf_alloc ! buffer to hold the region name +#endif + CHARACTER(LEN=16) :: buf_big ! buffer bigger than needed + INTEGER(SIZE_T) :: buf_size ! returned size of the region buffer name + INTEGER, TARGET :: a_data + TYPE(C_PTR) :: f_ptr + LOGICAL :: ref_eq + INTEGER(hssize_t) :: num_points_ret + + INTEGER(HID_T) :: memspace + + ! + ! Create a new file with Default file access and + ! file creation properties. + ! + CALL h5_fixname_f(filename, fix_filename, H5P_DEFAULT_F, error) + IF (error .NE. 0) THEN + WRITE(*,*) "Cannot modify filename" + STOP + ENDIF + CALL h5fcreate_f(fix_filename, H5F_ACC_TRUNC_F, file_id, error) + CALL check("h5fcreate_f",error,total_error) + + ! + ! Create a group inside the file + ! + CALL h5gcreate_f(file_id, groupname1, grp1_id, error) + CALL check("h5gcreate_f",error,total_error) + + ! + ! Create a group inside the group GROUP1 + ! + CALL h5gcreate_f(grp1_id, groupname2, grp2_id, error) + CALL check("h5gcreate_f",error,total_error) + + CALL H5Screate_f(H5S_SCALAR_F, sid, error) + CALL check("H5Screate_f",error,total_error) + CALL H5Acreate_f(grp2_id, attrname, H5T_NATIVE_INTEGER, sid, aid, error) + CALL check("H5Acreate_f",error,total_error) + + ! + ! Create an attribute + ! + a_data = 20 + f_ptr = C_LOC(a_data) + CALL H5Awrite_f(aid, H5T_NATIVE_INTEGER, f_ptr, error) + CALL check("H5Awrite_f",error,total_error) + + ! + ! Create dataspaces for datasets + ! + CALL h5screate_simple_f(rank, dims, space_id, error) + CALL check("h5screate_simple_f",error,total_error) + CALL h5screate_simple_f(rank, dimsr, spacer_id, error) + CALL check("h5screate_simple_f",error,total_error) + + ! + ! Create integer dataset + ! + CALL h5dcreate_f(file_id, dsetnamei, H5T_NATIVE_INTEGER, space_id, dset1_id, error) + CALL check("h5dcreate_f",error,total_error) + ! + ! Create dataset to store references to the objects + ! + CALL h5dcreate_f(file_id, dsetnamer, H5T_STD_REF, spacer_id, dsetr_id, error) + CALL check("h5dcreate_f",error,total_error) + ! + ! Create a datatype and store in the file + ! + CALL h5tcopy_f(H5T_NATIVE_REAL, type_id, error) + CALL check("h5tcopy_f",error,total_error) + CALL h5tcommit_f(file_id, "MyType", type_id, error) + CALL check("h5tcommit_f",error,total_error) + ! + ! Close dataspaces, groups and integer dataset + ! + CALL h5sclose_f(space_id, error) + CALL check("h5sclose_f",error,total_error) + CALL h5sclose_f(spacer_id, error) + CALL check("h5sclose_f",error,total_error) + CALL h5dclose_f(dset1_id, error) + CALL check("h5dclose_f",error,total_error) + CALL h5tclose_f(type_id, error) + CALL check("h5tclose_f",error,total_error) + CALL h5gclose_f(grp1_id, error) + CALL check("h5gclose_f",error,total_error) + CALL h5gclose_f(grp2_id, error) + CALL check("h5gclose_f",error,total_error) + CALL h5aclose_f(aid,error) + CALL check("H5Aclose_f",error,total_error) + CALL h5sclose_f(sid,error) + CALL check("H5Sclose_f",error,total_error) + ! + ! Create references to two groups, integer dataset, point selection and + ! shared datatype and write it to the dataset in the file + ! + f_ptr = C_LOC(ref_ptr(1)) + CALL h5rcreate_object_f(file_id, groupname1, f_ptr, error) + CALL check("h5rcreate_f",error,total_error) + f_ptr = C_LOC(ref_ptr(2)) + CALL h5rcreate_object_f(file_id, "/"//groupname1//"/"//groupname2, f_ptr, error) + CALL check("h5rcreate_f",error,total_error) + f_ptr = C_LOC(ref_ptr(3)) + CALL h5rcreate_object_f(file_id, dsetnamei, f_ptr, error) + CALL check("h5rcreate_f",error,total_error) + f_ptr = C_LOC(ref_ptr(4)) + CALL h5rcreate_object_f(file_id, "MyType", f_ptr, error) + CALL check("h5rcreate_f",error,total_error) + + f_ptr = C_LOC(ref_ptr(5)) + CALL h5rcreate_attr_f(file_id, "/"//groupname1//"/"//groupname2, attrname, f_ptr, error, H5P_DEFAULT_F) + CALL check("h5rcreate_attr_f",error,total_error) + + CALL h5screate_simple_f(1, dimspt, sid2, error) + CALL check("h5screate_simple_f",error,total_error) + + coord(1) = 1 + coord(2) = dims(1) + CALL h5sselect_elements_f(sid2, H5S_SELECT_SET_F, 1, SIZE(coord,KIND=SIZE_T), coord, error) + CALL check("h5sselect_elements_f",error,total_error) + + f_ptr = C_LOC(ref_ptr(6)) + CALL h5rcreate_region_f(file_id, dsetnamei, sid2, f_ptr, error) + CALL check("h5rcreate_region_f",error,total_error) + CALL h5rget_obj_name_f(C_LOC(ref_ptr(6)), buf_big, error) + + f_ptr = C_LOC(ref_ptr(1)) + CALL h5dwrite_f(dsetr_id, H5T_STD_REF, f_ptr, error) + CALL check("h5dwrite_f",error,total_error) + + CALL h5rget_obj_name_f(C_LOC(ref_ptr(3)), "", error, H5P_DEFAULT_F, buf_size) + CALL check("h5rget_obj_name_f", error, total_error) + CALL verify("h5rget_obj_name_f", buf_size, LEN(dsetnamei,KIND=SIZE_T)+1_SIZE_T, total_error) + CALL h5rget_obj_name_f(C_LOC(ref_ptr(1)), "", error, H5P_DEFAULT_F, buf_size) + CALL check("h5rget_obj_name_f", error, total_error) + CALL verify("h5rget_obj_name_f", buf_size, 7_SIZE_T, total_error) + +#ifdef H5_FORTRAN_HAVE_CHAR_ALLOC + ALLOCATE(CHARACTER(LEN=buf_size) :: buf_alloc) + CALL h5rget_obj_name_f(C_LOC(ref_ptr(1)), buf_alloc, error) + CALL check("h5rget_obj_name_f", error, total_error) + CALL VERIFY("h5rget_obj_name_f", buf_alloc, "/"//groupname1, total_error) + DEALLOCATE(buf_alloc) +#endif + ! with buffer bigger than needed + CALL h5rget_obj_name_f(C_LOC(ref_ptr(1)), buf_big, error) + CALL check("h5rget_obj_name_f", error, total_error) + CALL verify("h5rget_obj_name_f", TRIM(buf_big), "/"//groupname1, total_error) + + ! getting path to dataset + CALL h5rget_obj_name_f(C_LOC(ref_ptr(2)), "", error, name_len=buf_size ) + CALL check("H5Rget_name_f", error, total_error) + CALL verify("H5Rget_name_f2", INT(buf_size),LEN("/"//groupname1//"/"//groupname2),total_error) + +#ifdef H5_FORTRAN_HAVE_CHAR_ALLOC + ALLOCATE(CHARACTER(LEN=buf_size) :: buf_alloc) + CALL h5rget_obj_name_f(C_LOC(ref_ptr(2)), buf_alloc, error) + CALL check("h5rget_obj_name_f", error, total_error) + CALL VERIFY("h5rget_obj_name_f", buf_alloc, "/"//groupname1//"/"//groupname2, total_error) + DEALLOCATE(buf_alloc) +#endif + + CALL h5rget_obj_name_f(C_LOC(ref_ptr(2)), buf_big, error) + CALL check("H5Rget_name_f", error, total_error) + CALL verify("H5Rget_name_f", TRIM(buf_big), "/"//groupname1//"/"//groupname2, total_error) + + ! CHECK COPYING REF + + f_ptr = C_LOC(ref_ptr_cp) + CALL h5rcopy_f(C_LOC(ref_ptr(3)), f_ptr, error) + CALL check("h5rcopy_f", error, total_error) + + ! GET FILE NAME + CALL h5rget_file_name_f(f_ptr, "", error, buf_size) + CALL check("h5rget_file_name_f", error, total_error) + CALL verify("h5rget_file_name_f", buf_size, LEN_TRIM(fix_filename,KIND=SIZE_T), total_error) + +#ifdef H5_FORTRAN_HAVE_CHAR_ALLOC + ALLOCATE(CHARACTER(LEN=buf_size) :: buf_alloc) + CALL h5rget_file_name_f(f_ptr, buf_alloc, error) + CALL check("h5rget_file_name_f", error, total_error) + CALL VERIFY("h5rget_file_name_f", buf_alloc, TRIM(fix_filename), total_error) + DEALLOCATE(buf_alloc) +#endif + + ! Check with buffer bigger than needed + CALL h5rget_file_name_f(C_LOC(ref_ptr_cp), buf_big, error) + CALL check("h5rget_file_name_f", error, total_error) + CALL verify("h5rget_file_name_f", TRIM(buf_big), TRIM(fix_filename), total_error) + + ! CHECK EQUAL API + CALL h5requal_f(C_LOC(ref_ptr(3)), f_ptr, ref_eq, error) + CALL check("h5requal_f", error, total_error) + CALL VERIFY("h5requal_f", ref_eq, .TRUE., total_error) + + CALL h5requal_f(C_LOC(ref_ptr(1)), C_LOC(ref_ptr(3)), ref_eq, error) + CALL check("h5requal_f", error, total_error) + CALL VERIFY("h5requal_f", ref_eq, .FALSE., total_error) + + CALL h5rdestroy_f(f_ptr, error) + CALL check("h5rdestroy_f", error, total_error) + + ! + ! Close the dataset + ! + CALL h5dclose_f(dsetr_id, error) + CALL check("h5dclose_f",error,total_error) + + DO i = 1, ref_size + CALL h5rdestroy_f(C_LOC(ref_ptr(i)), error) + CALL check("h5rdestroy_f", error, total_error) + END DO + ! + ! Reopen the dataset with object references + ! + CALL h5dopen_f(file_id, dsetnamer,dsetr_id,error) + CALL check("h5dopen_f",error,total_error) + + ! Read the references dataset + f_ptr = C_LOC(ref_ptr_read(1)) + CALL h5dread_f(dsetr_id, H5T_STD_REF, f_ptr, error) + CALL check("h5dread_f",error,total_error) + + ! + ! Get information about the references read and check for correctness + ! + CALL h5rget_obj_name_f(C_LOC(ref_ptr_read(1)), buf_big, error) + CALL check("h5rget_obj_name_f", error, total_error) + CALL verify("h5rget_obj_name_f", TRIM(buf_big), "/"//groupname1, total_error) + CALL h5rget_obj_name_f(C_LOC(ref_ptr_read(2)), buf_big, error) + CALL check("h5rget_obj_name_f", error, total_error) + CALL verify("h5rget_obj_name_f", TRIM(buf_big), "/"//groupname1//"/"//groupname2, total_error) + CALL h5rget_obj_name_f(C_LOC(ref_ptr_read(3)), buf_big, error) + CALL check("h5rget_obj_name_f", error, total_error) + CALL verify("h5rget_obj_name_f", TRIM(buf_big), "/"//dsetnamei, total_error) + CALL h5rget_obj_name_f(C_LOC(ref_ptr_read(4)), buf_big, error) + CALL check("h5rget_obj_name_f", error, total_error) + CALL verify("h5rget_obj_name_f", TRIM(buf_big), "/"//"MyType", total_error) + + CALL h5rget_attr_name_f(C_LOC(ref_ptr_read(5)), buf_big, error, buf_size) + CALL check("h5rget_attr_name_f", error, total_error) + CALL VERIFY("h5rget_attr_name_f", buf_size, LEN(attrname, KIND=SIZE_T), total_error) + + CALL h5rget_attr_name_f(C_LOC(ref_ptr_read(5)), buf_big, error) + CALL check("h5rget_attr_name_f", error, total_error) + CALL verify("h5rget_attr_name_f", TRIM(buf_big), attrname, total_error) + + CALL h5ropen_attr_f( C_LOC(ref_ptr_read(5)), aid2, error, H5P_DEFAULT_F, H5P_DEFAULT_F ) + CALL check("h5ropen_attr_f",error,total_error) + + CALL h5aget_name_f(aid2, 16_size_t, buf_big, error) + CALL check("h5aget_name_f",error,total_error) + CALL verify("h5aget_name_f", TRIM(buf_big), attrname, total_error) + + CALL h5aclose_f(aid2, error) + CALL check("h5aclose_f", error, total_error) + + CALL h5rget_type_f(C_LOC(ref_ptr_read(1)), ref_type, error) + CALL check("h5rget_type_f", error, total_error) + CALL verify("h5rget_type_f", ref_type, H5R_OBJECT2_F, total_error) + + IF (ref_type == H5R_OBJECT2_F) THEN + CALL h5ropen_object_f(C_LOC(ref_ptr_read(3)), dset1_id, error, H5P_DEFAULT_F) + CALL check("h5ropen_object_f", error, total_error) + + CALL h5dwrite_f(dset1_id, H5T_NATIVE_INTEGER, C_LOC(data(1)), error) + CALL check("h5dwrite_f",error,total_error) + + CALL h5rdestroy_f(C_LOC(ref_ptr_read(3)), error) + CALL check("h5rdestroy_f", error, total_error) + + CALL h5oclose_f(dset1_id, error) + CALL check("h5oclose_f1",error,total_error) + + END IF + + CALL h5rget_type_f(C_LOC(ref_ptr_read(6)), ref_type, error) + CALL check("h5rget_type_f", error, total_error) + + IF(ref_type .EQ. H5R_DATASET_REGION2_F)THEN + CALL h5ropen_object_f(C_LOC(ref_ptr_read(6)), dset1_id, error, H5P_DEFAULT_F) + + CALL H5Dget_space_f(dset1_id, dspace_id1, error) + CALL check("H5Dget_space_f",error,total_error) + CALL H5Sget_simple_extent_npoints_f(dspace_id1, num_points_ret, error) + CALL VERIFY("H5Sget_simple_extent_npoints_f", num_points_ret, dims(1), total_error) + + CALL h5ropen_region_f(C_LOC(ref_ptr_read(6)), dspace_id, error, H5P_DEFAULT_F) + CALL check("h5ropen_object_f", error, total_error) + + CALL h5screate_simple_f(1, dimspt, memspace, error) + CALL check("h5screate_simple_f",error,total_error) + + CALL h5sget_select_elem_npoints_f(dspace_id, num_points_ret, error) + CALL check("h5sget_select_elem_npoints_f",error,total_error) + CALL VERIFY("h5sget_simple_extent_npoints_f", num_points_ret, 2_HSIZE_T, total_error) + + f_ptr = C_LOC(data_write(1)) + CALL h5dwrite_f(dset1_id, H5T_NATIVE_INTEGER, f_ptr, error, memspace, dspace_id) + CALL check("h5dwrite_f",error,total_error) + + CALL h5rdestroy_f(C_LOC(ref_ptr_read(6)), error) + CALL check("h5rdestroy_f", error, total_error) + + f_ptr = C_LOC(data(1)) + CALL h5dread_f(dset1_id, H5T_NATIVE_INTEGER, f_ptr, error) + CALL check("h5dread_f", error, total_error) + CALL VERIFY("h5dread_f", DATA(1), data_write(1), total_error) + CALL VERIFY("h5dread_f", DATA(5), data_write(2), total_error) + + CALL h5oclose_f(dset1_id, error) + CALL check("h5oclose_f",error,total_error) + ELSE + CALL check("h5rget_type_f", -1, total_error) + END IF + + ! + ! Close all objects. + ! + + CALL h5dclose_f(dsetr_id, error) + CALL check("h5dclose_f",error,total_error) + CALL h5fclose_f(file_id, error) + CALL check("h5fclose_f",error,total_error) + + DO i = 1, 4 + CALL h5rdestroy_f(C_LOC(ref_ptr_read(i)), error) + CALL check("h5rdestroy_f", error, total_error) + END DO + + IF(cleanup) CALL h5_cleanup_f(filename, H5P_DEFAULT_F, error) + CALL check("h5_cleanup_f", error, total_error) + + RETURN + +END SUBROUTINE v3reftest + END MODULE TH5R diff --git a/java/test/junit.sh.in b/java/test/junit.sh.in index 981d945965b..072edb4ff95 100644 --- a/java/test/junit.sh.in +++ b/java/test/junit.sh.in @@ -348,7 +348,7 @@ TESTING JUnit-TestH5 ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5 > JUnit-TestH5.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -369,7 +369,7 @@ TESTING JUnit-TestH5Eparams ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Eparams > JUnit-TestH5Eparams.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -390,7 +390,7 @@ TESTING JUnit-TestH5Eregister ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Eregister > JUnit-TestH5Eregister.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -411,7 +411,7 @@ TESTING JUnit-TestH5Fparams ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Fparams > JUnit-TestH5Fparams.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -432,7 +432,7 @@ TESTING JUnit-TestH5Fbasic ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Fbasic > JUnit-TestH5Fbasic.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -453,7 +453,7 @@ TESTING JUnit-TestH5F ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5F > JUnit-TestH5F.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -474,7 +474,7 @@ TESTING JUnit-TestH5Fswmr ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Fswmr > JUnit-TestH5Fswmr.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -495,7 +495,7 @@ TESTING JUnit-TestH5Gbasic ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Gbasic > JUnit-TestH5Gbasic.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -516,7 +516,7 @@ TESTING JUnit-TestH5G ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5G > JUnit-TestH5G.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -537,7 +537,7 @@ TESTING JUnit-TestH5Sbasic ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Sbasic > JUnit-TestH5Sbasic.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -558,7 +558,7 @@ TESTING JUnit-TestH5S ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5S > JUnit-TestH5S.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -579,7 +579,7 @@ TESTING JUnit-TestH5Tparams ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Tparams > JUnit-TestH5Tparams.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -600,7 +600,7 @@ TESTING JUnit-TestH5Tbasic ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Tbasic > JUnit-TestH5Tbasic.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -621,7 +621,7 @@ TESTING JUnit-TestH5T ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5T > JUnit-TestH5T.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -642,7 +642,7 @@ TESTING JUnit-TestH5Dparams ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Dparams > JUnit-TestH5Dparams.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -663,7 +663,7 @@ TESTING JUnit-TestH5D ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5D > JUnit-TestH5D.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -684,7 +684,7 @@ TESTING JUnit-TestH5Drw ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Drw > JUnit-TestH5Drw.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -705,7 +705,7 @@ TESTING JUnit-TestH5Dplist ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Dplist > JUnit-TestH5Dplist.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -726,7 +726,7 @@ TESTING JUnit-TestH5Lparams ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Lparams > JUnit-TestH5Lparams.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -747,7 +747,7 @@ TESTING JUnit-TestH5Lbasic ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Lbasic > JUnit-TestH5Lbasic.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -768,7 +768,7 @@ TESTING JUnit-TestH5Lcreate ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Lcreate > JUnit-TestH5Lcreate.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -789,7 +789,7 @@ TESTING JUnit-TestH5R ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5R > JUnit-TestH5R.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -810,7 +810,7 @@ TESTING JUnit-TestH5Rref ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Rref > JUnit-TestH5Rref.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -831,7 +831,7 @@ TESTING JUnit-TestH5P ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5P > JUnit-TestH5P.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -852,7 +852,7 @@ TESTING JUnit-TestH5PData ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5PData > JUnit-TestH5PData.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -873,7 +873,7 @@ TESTING JUnit-TestH5Pfapl ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Pfapl > JUnit-TestH5Pfapl.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -894,7 +894,7 @@ TESTING JUnit-TestH5Pvirtual ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Pvirtual > JUnit-TestH5Pvirtual.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -915,7 +915,7 @@ TESTING JUnit-TestH5Plist ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Plist > JUnit-TestH5Plist.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -936,7 +936,7 @@ TESTING JUnit-TestH5A ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5A > JUnit-TestH5A.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -957,7 +957,7 @@ TESTING JUnit-TestH5Arw ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Arw > JUnit-TestH5Arw.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -978,7 +978,7 @@ TESTING JUnit-TestH5Oparams ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Oparams > JUnit-TestH5Oparams.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -999,7 +999,7 @@ TESTING JUnit-TestH5Obasic ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Obasic > JUnit-TestH5Obasic.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1020,7 +1020,7 @@ TESTING JUnit-TestH5Ocreate ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Ocreate > JUnit-TestH5Ocreate.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1041,7 +1041,7 @@ TESTING JUnit-TestH5OcopyOld ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5OcopyOld > JUnit-TestH5OcopyOld.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1062,7 +1062,7 @@ TESTING JUnit-TestH5Ocopy ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Ocopy > JUnit-TestH5Ocopy.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1083,7 +1083,7 @@ TESTING JUnit-TestH5PL ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5PL > JUnit-TestH5PL.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1104,7 +1104,7 @@ TESTING JUnit-TestH5VL ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5VL > JUnit-TestH5VL.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1125,7 +1125,7 @@ TESTING JUnit-TestH5Z ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Z > JUnit-TestH5Z.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1146,7 +1146,7 @@ TESTING JUnit-TestH5E ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5E > JUnit-TestH5E.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1167,7 +1167,7 @@ TESTING JUnit-TestH5Edefault ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Edefault > JUnit-TestH5Edefault.ext) # Extract file name, line number, version and thread IDs because they may be different -sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ +sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1189,7 +1189,7 @@ if test $USE_FILTER_SZIP = "yes"; then ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Giterate > JUnit-TestH5Giterate.ext) # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ + sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*[\.,[0-9]*]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1211,7 +1211,7 @@ if test "X$ROS3_VFD" = "Xyes"; then ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Pfapls3 > JUnit-TestH5Pfapls3.ext) # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ + sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*\.,[0-9]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ @@ -1233,7 +1233,7 @@ if test "X$HAVE_LIBHDFS" = "Xyes"; then ($RUNSERIAL $JAVAEXE $JAVAEXEFLAGS -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=trace -Djava.library.path=$BLDLIBDIR -cp $CLASSPATH -ea org.junit.runner.JUnitCore test.TestH5Pfaplhdfs > JUnit-TestH5Pfaplhdfs.ext) # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ + sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/Time: [0-9]*\.,[0-9]*/Time: XXXX/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ diff --git a/release_docs/INSTALL_CMake.txt b/release_docs/INSTALL_CMake.txt index 02f0a754cce..d36e80e1027 100644 --- a/release_docs/INSTALL_CMake.txt +++ b/release_docs/INSTALL_CMake.txt @@ -842,7 +842,6 @@ HDF5_EXTERNAL_LIB_PREFIX "Use prefix for custom library naming." HDF5_DISABLE_COMPILER_WARNINGS "Disable compiler warnings" OFF HDF5_ENABLE_ALL_WARNINGS "Enable all warnings" OFF HDF5_SHOW_ALL_WARNINGS "Show all warnings (i.e. not suppress "noisy" ones internally)" OFF -HDF5_ENABLE_CODESTACK "Enable the function stack tracing (for developer debugging)." OFF HDF5_ENABLE_COVERAGE "Enable code coverage for Libraries and Programs" OFF HDF5_ENABLE_DEBUG_APIS "Turn on extra debug output in all packages" OFF HDF5_ENABLE_DEPRECATED_SYMBOLS "Enable deprecated public API symbols" ON diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 51c0cea0923..88cd0dc43ff 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -36,7 +36,7 @@ CONTENTS - New Features - Support for new platforms and languages -- Bug Fixes since HDF5-1.14.3 +- Bug Fixes since HDF5-1.14.4 - Platforms Tested - Known Problems - CMake vs. Autotools installations @@ -47,6 +47,16 @@ New Features Configuration: ------------- + - Removed "function/code stack" debugging configuration option: + + CMake: HDF5_ENABLE_CODESTACK + Autotools: --enable-codestack + + This was used to debug memory leaks internal to the library, but has been + broken for >1.5 years and is now easily replaced with third-party tools + (e.g. libbacktrace: https://github.com/ianlancetaylor/libbacktrace) on an + as-needed basis when debugging an issue. + - Added configure options for enabling/disabling non-standard programming language features @@ -410,6 +420,13 @@ New Features Fortran Library: ---------------- + + - Add Fortran H5R APIs: + h5rcreate_attr_f, h5rcreate_object_f, h5rcreate_region_f, + h5ropen_attr_f, h5ropen_object_f, h5ropen_region_f, + h5rget_file_name_f, h5rget_attr_name_f, h5rget_obj_name_f, + h5rcopy_f, h5requal_f, h5rdestroy_f, h5rget_type_f + - Added Fortran H5E APIs: h5eregister_class_f, h5eunregister_class_f, h5ecreate_msg_f, h5eclose_msg_f h5eget_msg_f, h5epush_f, h5eget_num_f, h5ewalk_f, h5eget_class_name_f, @@ -481,24 +498,30 @@ Support for new platforms, languages and compilers - -Bug Fixes since HDF5-1.14.3 release +Bug Fixes since HDF5-1.14.4 release =================================== - Configuration: - ------------- - - Fix Autotools -Werror cleanup + Library + ------- - The Autotools temporarily scrub -Werror(=whatever) from CFLAGS, etc. - so configure checks don't trip over warnings generated by configure - check programs. The sed line originally only scrubbed -Werror but not - -Werror=something, which would cause errors when the '=something' was - left behind in CFLAGS. + - Fixed function H5Requal actually to compare the reference pointers - The sed line has been updated to handle -Werror=something lines. + Fixed an issue with H5Requal always returning true because the + function was only comparing the ref2_ptr to itself. - Fixes one issue raised in #3872 + - Fixed infinite loop closing library issue when h5dump with a user provided test file + + The library's metadata cache calls the "get_final_load_size" client callback + to find out the actual size of the object header. As the size obtained + exceeds the file's EOA, it throws an error but the object header structure + allocated through the client callback is not freed hence causing the + issue described. + + (1) Free the structure allocated in the object header client callback after + saving the needed information in udata. (2) Deserialize the object header + prefix in the object header's "deserialize" callback regardless. + + Fixes GitHub #3790 - Library - ------- - Fixed many (future) CVE issues A partner organization corrected many potential security issues, which @@ -997,6 +1020,24 @@ Bug Fixes since HDF5-1.14.3 release Configuration ------------- + - Fixed a list index out of range issue in the runTest.cmake file + + Fixed an issue in config/cmake/runTest.cmake where the CMake logic + would try to access an invalid list index if the number of lines in + a test's output and reference files don't match + + - Fix Autotools -Werror cleanup + + The Autotools temporarily scrub -Werror(=whatever) from CFLAGS, etc. + so configure checks don't trip over warnings generated by configure + check programs. The sed line originally only scrubbed -Werror but not + -Werror=something, which would cause errors when the '=something' was + left behind in CFLAGS. + + The sed line has been updated to handle -Werror=something lines. + + Fixes one issue raised in #3872 + - Changed default of 'Error on HDF5 doxygen warnings' DOXYGEN_WARN_AS_ERROR option. The default setting of DOXYGEN_WARN_AS_ERROR to 'FAIL_ON_WARNINGS' has been changed @@ -1029,6 +1070,20 @@ Bug Fixes since HDF5-1.14.3 release Tools ----- + - Fixed several issues in ph5diff + + The parallel logic for the ph5diff tool inside the shared h5diff code was + refactored and cleaned up to fix several issues with the ph5diff tool. This + fixed: + + - several concurrency issues in ph5diff that can result in interleaved + output + - an issue where output can sometimes be dropped when it ends up in + ph5diff's output overflow file + - an issue where MPI_Init was called after HDF5 had been initialized, + preventing the library from setting up an MPI communicator attribute + to perform library cleanup on MPI_Finalize + - Renamed h5fuse.sh to h5fuse Addresses Discussion #3791 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a19126c8291..8ff62e8c9f9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -99,14 +99,6 @@ set (H5C_HDRS IDE_GENERATED_PROPERTIES ("H5C" "${H5C_HDRS}" "${H5C_SOURCES}" ) -set (H5CS_SOURCES - ${HDF5_SRC_DIR}/H5CS.c -) -set (H5CS_HDRS -) -IDE_GENERATED_PROPERTIES ("H5CS" "${H5CS_HDRS}" "${H5CS_SOURCES}" ) - - set (H5CX_SOURCES ${HDF5_SRC_DIR}/H5CX.c ) @@ -610,6 +602,15 @@ set (H5T_SOURCES ${HDF5_SRC_DIR}/H5Tcommit.c ${HDF5_SRC_DIR}/H5Tcompound.c ${HDF5_SRC_DIR}/H5Tconv.c + ${HDF5_SRC_DIR}/H5Tconv_integer.c + ${HDF5_SRC_DIR}/H5Tconv_float.c + ${HDF5_SRC_DIR}/H5Tconv_string.c + ${HDF5_SRC_DIR}/H5Tconv_bitfield.c + ${HDF5_SRC_DIR}/H5Tconv_compound.c + ${HDF5_SRC_DIR}/H5Tconv_reference.c + ${HDF5_SRC_DIR}/H5Tconv_enum.c + ${HDF5_SRC_DIR}/H5Tconv_vlen.c + ${HDF5_SRC_DIR}/H5Tconv_array.c ${HDF5_SRC_DIR}/H5Tcset.c ${HDF5_SRC_DIR}/H5Tdbg.c ${HDF5_SRC_DIR}/H5Tdeprec.c @@ -768,7 +769,6 @@ set (common_SRCS ${H5B_SOURCES} ${H5B2_SOURCES} ${H5C_SOURCES} - ${H5CS_SOURCES} ${H5CX_SOURCES} ${H5D_SOURCES} ${H5E_SOURCES} @@ -863,8 +863,6 @@ set (H5_PRIVATE_HEADERS ${HDF5_SRC_DIR}/H5Cpkg.h ${HDF5_SRC_DIR}/H5Cprivate.h - ${HDF5_SRC_DIR}/H5CSprivate.h - ${HDF5_SRC_DIR}/H5CXprivate.h ${HDF5_SRC_DIR}/H5Dpkg.h @@ -955,6 +953,17 @@ set (H5_PRIVATE_HEADERS ${HDF5_SRC_DIR}/H5SMpkg.h ${HDF5_SRC_DIR}/H5SMprivate.h + ${HDF5_SRC_DIR}/H5Tconv.h + ${HDF5_SRC_DIR}/H5Tconv_array.h + ${HDF5_SRC_DIR}/H5Tconv_bitfield.h + ${HDF5_SRC_DIR}/H5Tconv_compound.h + ${HDF5_SRC_DIR}/H5Tconv_enum.h + ${HDF5_SRC_DIR}/H5Tconv_float.h + ${HDF5_SRC_DIR}/H5Tconv_integer.h + ${HDF5_SRC_DIR}/H5Tconv_macros.h + ${HDF5_SRC_DIR}/H5Tconv_reference.h + ${HDF5_SRC_DIR}/H5Tconv_string.h + ${HDF5_SRC_DIR}/H5Tconv_vlen.h ${HDF5_SRC_DIR}/H5Tpkg.h ${HDF5_SRC_DIR}/H5Tprivate.h diff --git a/src/H5B2cache.c b/src/H5B2cache.c index 8ff0a45d370..c78b54c33f5 100644 --- a/src/H5B2cache.c +++ b/src/H5B2cache.c @@ -194,17 +194,19 @@ H5B2__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2__cache_hdr_verify_chksum() */ @@ -557,7 +559,7 @@ H5B2__cache_int_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, voi uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); @@ -568,11 +570,13 @@ H5B2__cache_int_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, voi ((size_t)(udata->nrec + 1) * H5B2_INT_POINTER_SIZE(udata->hdr, udata->depth)); /* Get stored and computed checksums */ - H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2__cache_int_verify_chksum() */ @@ -956,7 +960,7 @@ H5B2__cache_leaf_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, vo uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); @@ -966,11 +970,13 @@ H5B2__cache_leaf_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, vo chk_size = H5B2_LEAF_PREFIX_SIZE + (udata->nrec * udata->hdr->rrec_size); /* Get stored and computed checksums */ - H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2__cache_leaf_verify_chksum() */ diff --git a/src/H5CS.c b/src/H5CS.c deleted file mode 100644 index 0dca211604f..00000000000 --- a/src/H5CS.c +++ /dev/null @@ -1,293 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Purpose: Provides internal function tracing in the form of a stack. - * The FUNC_ENTER() macro adds the function name to the function - * stack whenever a function is entered. - * As the functions return with FUNC_LEAVE, - * entries are removed from the stack. - * - * A function stack has a fixed maximum size. If this size is - * exceeded then the stack will be truncated and only the - * first called functions will have entries on the stack. This is - * expected to be a rare condition. - * - */ - -#include "H5private.h" /* Generic Functions */ -#include "H5CSprivate.h" /* Function stack */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5MMprivate.h" /* Memory management */ - -#ifdef H5_HAVE_CODESTACK - -#define H5CS_MIN_NSLOTS 16 /* Minimum number of records in an function stack */ - -/* A function stack */ -typedef struct H5CS_t { - unsigned nused; /* Number of records currently used in stack */ - unsigned nalloc; /* Number of records current allocated for stack */ - const char **rec; /* Array of function records */ -} H5CS_t; - -#ifdef H5_HAVE_THREADSAFE -/* - * The per-thread function stack. pthread_once() initializes a special - * key that will be used by all threads to create a stack specific to - * each thread individually. The association of stacks to threads will - * be handled by the pthread library. - * - * In order for this macro to work, H5CS_get_my_stack() must be preceded - * by "H5CS_t *fstack =". - */ -static H5CS_t *H5CS__get_stack(void); -#define H5CS_get_my_stack() H5CS__get_stack() -#else /* H5_HAVE_THREADSAFE */ -/* - * The function stack. Eventually we'll have some sort of global table so each - * thread has it's own stack. The stacks will be created on demand when the - * thread first calls H5CS_push(). */ -H5CS_t H5CS_stack_g[1]; -#define H5CS_get_my_stack() (H5CS_stack_g + 0) -#endif /* H5_HAVE_THREADSAFE */ - -#ifdef H5_HAVE_THREADSAFE -/*------------------------------------------------------------------------- - * Function: H5CS__get_stack - * - * Purpose: Support function for H5CS_get_my_stack() to initialize and - * acquire per-thread function stack. - * - * Return: Success: function stack (H5CS_t *) - * - * Failure: NULL - * - *------------------------------------------------------------------------- - */ -static H5CS_t * -H5CS__get_stack(void) -{ - H5CS_t *fstack; - - FUNC_ENTER_PACKAGE_NOERR_NOFS - - fstack = H5TS_get_thread_local_value(H5TS_funcstk_key_g); - if (!fstack) { - /* No associated value with current thread - create one */ -#ifdef H5_HAVE_WIN_THREADS - fstack = (H5CS_t *)LocalAlloc( - LPTR, sizeof(H5CS_t)); /* Win32 has to use LocalAlloc to match the LocalFree in DllMain */ -#else - fstack = - (H5CS_t *)malloc(sizeof(H5CS_t)); /* Don't use H5MM_malloc() here, it causes infinite recursion */ -#endif /* H5_HAVE_WIN_THREADS */ - assert(fstack); - - /* Set the thread-specific info */ - fstack->nused = 0; - fstack->nalloc = 0; - fstack->rec = NULL; - - /* (It's not necessary to release this in this API, it is - * released by the "key destructor" set up in the H5TS - * routines. See calls to pthread_key_create() in H5TS.c -QAK) - */ - H5TS_set_thread_local_value(H5TS_funcstk_key_g, (void *)fstack); - } /* end if */ - - FUNC_LEAVE_NOAPI_NOFS(fstack) -} /* end H5CS__get_stack() */ -#endif /* H5_HAVE_THREADSAFE */ - -/*------------------------------------------------------------------------- - * Function: H5CS_print_stack - * - * Purpose: Prints a function stack. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5CS_print_stack(const H5CS_t *fstack, FILE *stream) -{ - const int indent = 2; /* Indentation level */ - int i; /* Local index ariable */ - - /* Don't push this function on the function stack... :-) */ - FUNC_ENTER_NOAPI_NOERR_NOFS - - /* Sanity check */ - assert(fstack); - - /* Default to outputting information to stderr */ - if (!stream) - stream = stderr; - - fprintf(stream, "HDF5-DIAG: Function stack from %s ", H5_lib_vers_info_g); - /* try show the process or thread id in multiple processes cases*/ - fprintf(stream, "thread %" PRIu64 ".", H5TS_thread_id()); - if (fstack && fstack->nused > 0) - fprintf(stream, " Back trace follows."); - fputc('\n', stream); - - for (i = fstack->nused - 1; i >= 0; --i) - fprintf(stream, "%*s#%03d: Routine: %s\n", indent, "", i, fstack->rec[i]); - - FUNC_LEAVE_NOAPI_NOFS(SUCCEED) -} /* end H5CS_print_stack() */ - -/*------------------------------------------------------------------------- - * Function: H5CS_push - * - * Purpose: Pushes a new record onto function stack for the current - * thread. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5CS_push(const char *func_name) -{ - H5CS_t *fstack = H5CS_get_my_stack(); /* Current function stack for library */ - - /* Don't push this function on the function stack... :-) */ - FUNC_ENTER_NOAPI_NOERR_NOFS - - /* Sanity check */ - assert(fstack); - assert(fstack->nused <= fstack->nalloc); - assert(func_name); - - /* Check if we need to expand the stack of records */ - if (fstack->nused == fstack->nalloc) { - size_t na = MAX((fstack->nalloc * 2), H5CS_MIN_NSLOTS); - - /* Don't use H5MM_realloc here */ - const char **x = (const char **)realloc(fstack->rec, na * sizeof(const char *)); - - /* (Avoid returning an error from this routine, currently -QAK) */ - assert(x); - fstack->rec = x; - fstack->nalloc = na; - } /* end if */ - - /* Push the function name */ - fstack->rec[fstack->nused] = func_name; - fstack->nused++; - - FUNC_LEAVE_NOAPI_NOFS(SUCCEED) -} /* end H5CS_push() */ - -/*------------------------------------------------------------------------- - * Function: H5CS_pop - * - * Purpose: Pops a record off function stack for the current thread. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5CS_pop(void) -{ - H5CS_t *fstack = H5CS_get_my_stack(); - - /* Don't push this function on the function stack... :-) */ - FUNC_ENTER_NOAPI_NOERR_NOFS - - /* Sanity check */ - assert(fstack); - assert(fstack->nused > 0); - - /* Pop the function. */ - fstack->nused--; - - FUNC_LEAVE_NOAPI_NOFS(SUCCEED) -} /* end H5CS_pop() */ - -/*------------------------------------------------------------------------- - * Function: H5CS_copy_stack - * - * Purpose: Makes a copy of the current stack - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -H5CS_t * -H5CS_copy_stack(void) -{ - H5CS_t *old_stack = H5CS_get_my_stack(); /* Existing function stack for library */ - H5CS_t *new_stack; /* New function stack, for copy */ - H5CS_t *ret_value = NULL; /* Return value */ - - /* Don't push this function on the function stack... :-) */ - FUNC_ENTER_NOAPI_NOFS - - /* Sanity check */ - assert(old_stack); - - /* Allocate a new stack */ - /* (Don't use library allocate code, since this code stack supports it) */ - if (NULL == (new_stack = calloc(1, sizeof(H5CS_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate function stack"); - if (NULL == (new_stack->rec = calloc(old_stack->nused, sizeof(const char *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate function stack records"); - - /* Copy pointers on old stack to new one */ - /* (Strings don't need to be duplicated, they are statically allocated) */ - H5MM_memcpy(new_stack->rec, old_stack->rec, sizeof(char *) * old_stack->nused); - new_stack->nused = new_stack->nalloc = old_stack->nused; - - /* Set the return value */ - ret_value = new_stack; - -done: - FUNC_LEAVE_NOAPI_NOFS(ret_value) -} /* end H5CS_copy_stack() */ - -/*------------------------------------------------------------------------- - * Function: H5CS_close_stack - * - * Purpose: Closes and frees a copy of a stack - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5CS_close_stack(H5CS_t *stack) -{ - /* Don't push this function on the function stack... :-) */ - FUNC_ENTER_NOAPI_NOERR_NOFS - - /* Sanity check */ - assert(stack); - - /* Free stack */ - /* The function name string are statically allocated (by the compiler) - * and are not allocated, so there's no need to free them. - */ - if (stack->rec) { - free(stack->rec); - stack->rec = NULL; - } /* end if */ - if (stack) - free(stack); - - FUNC_LEAVE_NOAPI_NOFS(SUCCEED) -} /* end H5CS_close_stack() */ - -#endif /* H5_HAVE_CODESTACK */ diff --git a/src/H5E.c b/src/H5E.c index 755172c755d..4f2edd78ebf 100644 --- a/src/H5E.c +++ b/src/H5E.c @@ -91,6 +91,12 @@ static herr_t H5E__append_stack(H5E_t *dst_estack, const H5E_t *src_stack); /* Package Variables */ /*********************/ +/* First & last major and minor error codes registered by the library */ +hid_t H5E_first_maj_id_g = H5I_INVALID_HID; +hid_t H5E_last_maj_id_g = H5I_INVALID_HID; +hid_t H5E_first_min_id_g = H5I_INVALID_HID; +hid_t H5E_last_min_id_g = H5I_INVALID_HID; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -435,11 +441,11 @@ H5E__register_class(const char *cls_name, const char *lib_name, const char *vers HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Duplicate string information */ - if (NULL == (cls->cls_name = H5MM_xstrdup(cls_name))) + if (NULL == (cls->cls_name = strdup(cls_name))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - if (NULL == (cls->lib_name = H5MM_xstrdup(lib_name))) + if (NULL == (cls->lib_name = strdup(lib_name))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - if (NULL == (cls->lib_vers = H5MM_xstrdup(version))) + if (NULL == (cls->lib_vers = strdup(version))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Set the return value */ @@ -738,7 +744,7 @@ H5E__create_msg(H5E_cls_t *cls, H5E_type_t msg_type, const char *msg_str) /* Fill new message object */ msg->cls = cls; msg->type = msg_type; - if (NULL == (msg->msg = H5MM_xstrdup(msg_str))) + if (NULL == (msg->msg = strdup(msg_str))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Set return value */ @@ -884,24 +890,11 @@ H5E__get_current_stack(void) current_error = &(current_stack->slot[u]); new_error = &(estack_copy->slot[u]); - /* Increment the IDs to indicate that they are used in this stack */ - if (H5I_inc_ref(current_error->cls_id, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error class"); - new_error->cls_id = current_error->cls_id; - if (H5I_inc_ref(current_error->maj_num, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error message"); - new_error->maj_num = current_error->maj_num; - if (H5I_inc_ref(current_error->min_num, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error message"); - new_error->min_num = current_error->min_num; - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - new_error->func_name = current_error->func_name; - new_error->file_name = current_error->file_name; - new_error->line = current_error->line; - if (NULL == (new_error->desc = H5MM_xstrdup(current_error->desc))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + /* Set error stack entry */ + if (H5E__set_stack_entry(new_error, current_error->file_name, current_error->func_name, + current_error->line, current_error->cls_id, current_error->maj_num, + current_error->min_num, current_error->desc) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, NULL, "can't set error entry"); } /* end for */ /* Copy the "automatic" error reporting information */ @@ -997,24 +990,11 @@ H5E__set_current_stack(H5E_t *estack) current_error = &(current_stack->slot[u]); new_error = &(estack->slot[u]); - /* Increment the IDs to indicate that they are used in this stack */ - if (H5I_inc_ref(new_error->cls_id, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class"); - current_error->cls_id = new_error->cls_id; - if (H5I_inc_ref(new_error->maj_num, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class"); - current_error->maj_num = new_error->maj_num; - if (H5I_inc_ref(new_error->min_num, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class"); - current_error->min_num = new_error->min_num; - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - current_error->func_name = new_error->func_name; - current_error->file_name = new_error->file_name; - current_error->line = new_error->line; - if (NULL == (current_error->desc = H5MM_xstrdup(new_error->desc))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + /* Set error stack entry */ + if (H5E__set_stack_entry(current_error, new_error->file_name, new_error->func_name, new_error->line, + new_error->cls_id, new_error->maj_num, new_error->min_num, + new_error->desc) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set error entry"); } /* end for */ done: @@ -1635,24 +1615,11 @@ H5E__append_stack(H5E_t *dst_stack, const H5E_t *src_stack) src_error = &(src_stack->slot[u]); dst_error = &(dst_stack->slot[dst_stack->nused]); - /* Increment the IDs to indicate that they are used in this stack */ - if (H5I_inc_ref(src_error->cls_id, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class"); - dst_error->cls_id = src_error->cls_id; - if (H5I_inc_ref(src_error->maj_num, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error message"); - dst_error->maj_num = src_error->maj_num; - if (H5I_inc_ref(src_error->min_num, false) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error message"); - dst_error->min_num = src_error->min_num; - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - dst_error->func_name = src_error->func_name; - dst_error->file_name = src_error->file_name; - dst_error->line = src_error->line; - if (NULL == (dst_error->desc = H5MM_xstrdup(src_error->desc))) - HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed"); + /* Set error stack entry */ + if (H5E__set_stack_entry(dst_error, src_error->file_name, src_error->func_name, src_error->line, + src_error->cls_id, src_error->maj_num, src_error->min_num, + src_error->desc) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set error entry"); /* Increment # of errors in destination stack */ dst_stack->nused++; diff --git a/src/H5EAcache.c b/src/H5EAcache.c index 74a3abe2189..951c40dccc1 100644 --- a/src/H5EAcache.c +++ b/src/H5EAcache.c @@ -249,17 +249,19 @@ H5EA__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_hdr_verify_chksum() */ @@ -639,17 +641,19 @@ H5EA__cache_iblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_iblock_verify_chksum() */ @@ -1039,17 +1043,19 @@ H5EA__cache_sblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_sblock_verify_chksum() */ @@ -1445,17 +1451,19 @@ H5EA__cache_dblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_sblock_verify_chksum() */ @@ -1866,17 +1874,19 @@ H5EA__cache_dblk_page_verify_chksum(const void *_image, size_t len, void H5_ATTR uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_dblk_page_verify_chksum() */ diff --git a/src/H5Eint.c b/src/H5Eint.c index 70848ecd7c2..e59988d0264 100644 --- a/src/H5Eint.c +++ b/src/H5Eint.c @@ -218,7 +218,7 @@ H5E__walk1_cb(int n, H5E_error1_t *err_desc, void *client_data) if (cls_ptr->lib_vers) eprint->cls.lib_vers = cls_ptr->lib_vers; - fprintf(stream, "%s-DIAG: Error detected in %s (%s) ", + fprintf(stream, "%s-DIAG: Error detected in %s (%s)", (cls_ptr->cls_name ? cls_ptr->cls_name : "(null)"), (cls_ptr->lib_name ? cls_ptr->lib_name : "(null)"), (cls_ptr->lib_vers ? cls_ptr->lib_vers : "(null)")); @@ -233,13 +233,17 @@ H5E__walk1_cb(int n, H5E_error1_t *err_desc, void *client_data) if (mpi_initialized && !mpi_finalized) { MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); - fprintf(stream, "MPI-process %d", mpi_rank); + fprintf(stream, " MPI-process %d", mpi_rank); } /* end if */ +#ifdef H5_HAVE_THREADSAFE else - fprintf(stream, "thread 0"); + fprintf(stream, " thread %" PRIu64, H5TS_thread_id()); +#endif } /* end block */ #else - fprintf(stream, "thread %" PRIu64, H5TS_thread_id()); +#ifdef H5_HAVE_THREADSAFE + fprintf(stream, " thread %" PRIu64, H5TS_thread_id()); +#endif #endif fprintf(stream, ":\n"); } /* end if */ @@ -342,7 +346,7 @@ H5E__walk2_cb(unsigned n, const H5E_error2_t *err_desc, void *client_data) if (cls_ptr->lib_vers) eprint->cls.lib_vers = cls_ptr->lib_vers; - fprintf(stream, "%s-DIAG: Error detected in %s (%s) ", + fprintf(stream, "%s-DIAG: Error detected in %s (%s)", (cls_ptr->cls_name ? cls_ptr->cls_name : "(null)"), (cls_ptr->lib_name ? cls_ptr->lib_name : "(null)"), (cls_ptr->lib_vers ? cls_ptr->lib_vers : "(null)")); @@ -357,13 +361,17 @@ H5E__walk2_cb(unsigned n, const H5E_error2_t *err_desc, void *client_data) if (mpi_initialized && !mpi_finalized) { MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); - fprintf(stream, "MPI-process %d", mpi_rank); + fprintf(stream, " MPI-process %d", mpi_rank); } /* end if */ +#ifdef H5_HAVE_THREADSAFE else - fprintf(stream, "thread 0"); + fprintf(stream, " thread %" PRIu64, H5TS_thread_id()); +#endif } /* end block */ #else - fprintf(stream, "thread %" PRIu64, H5TS_thread_id()); +#ifdef H5_HAVE_THREADSAFE + fprintf(stream, " thread %" PRIu64, H5TS_thread_id()); +#endif #endif fprintf(stream, ":\n"); } /* end if */ @@ -712,6 +720,50 @@ H5E__push_stack(H5E_t *estack, const char *file, const char *func, unsigned line if (NULL == (estack = H5E__get_my_stack())) HGOTO_DONE(FAIL); + /* + * Push the error if there's room. Otherwise just forget it. + */ + if (estack->nused < H5E_NSLOTS) { + if (H5E__set_stack_entry(&estack->slot[estack->nused], file, func, line, cls_id, maj_id, min_id, + desc) < 0) + HGOTO_DONE(FAIL); + estack->nused++; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5E__push_stack() */ + +/*------------------------------------------------------------------------- + * Function: H5E__set_stack_entry + * + * Purpose: Sets the information for a given stack entry. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5E__set_stack_entry(H5E_error2_t *err_entry, const char *file, const char *func, unsigned line, hid_t cls_id, + hid_t maj_id, hid_t min_id, const char *desc) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + /* + * WARNING: We cannot call HERROR() from within this function or else we + * could enter infinite recursion. Furthermore, we also cannot + * call any other HDF5 macro or function which might call + * HERROR(). HERROR() is called by HRETURN_ERROR() which could + * be called by FUNC_ENTER(). + */ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity check */ + assert(err_entry); + assert(cls_id > 0); + assert(maj_id > 0); + assert(min_id > 0); + /* * Don't fail if arguments are bad. Instead, substitute some default * value. @@ -723,36 +775,32 @@ H5E__push_stack(H5E_t *estack, const char *file, const char *func, unsigned line if (!desc) desc = "No description given"; - /* - * Push the error if there's room. Otherwise just forget it. - */ - assert(estack); - - if (estack->nused < H5E_NSLOTS) { - /* Increment the IDs to indicate that they are used in this stack */ + /* Increment the IDs to indicate that they are used in this stack */ + /* Note: don't waste time incrementing library internal error IDs */ + if (cls_id != H5E_ERR_CLS_g) if (H5I_inc_ref_noherr(cls_id, false) < 0) HGOTO_DONE(FAIL); - estack->slot[estack->nused].cls_id = cls_id; + err_entry->cls_id = cls_id; + if (maj_id < H5E_first_maj_id_g || maj_id > H5E_last_maj_id_g) if (H5I_inc_ref_noherr(maj_id, false) < 0) HGOTO_DONE(FAIL); - estack->slot[estack->nused].maj_num = maj_id; + err_entry->maj_num = maj_id; + if (min_id < H5E_first_min_id_g || min_id > H5E_last_min_id_g) if (H5I_inc_ref_noherr(min_id, false) < 0) HGOTO_DONE(FAIL); - estack->slot[estack->nused].min_num = min_id; - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - estack->slot[estack->nused].func_name = func; - estack->slot[estack->nused].file_name = file; - estack->slot[estack->nused].line = line; - if (NULL == (estack->slot[estack->nused].desc = H5MM_xstrdup(desc))) - HGOTO_DONE(FAIL); - estack->nused++; - } /* end if */ + err_entry->min_num = min_id; + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + err_entry->func_name = func; + err_entry->file_name = file; + err_entry->line = line; + if (NULL == (err_entry->desc = strdup(desc))) + HGOTO_DONE(FAIL); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5E__push_stack() */ +} /* end H5E__set_stack_entry() */ /*------------------------------------------------------------------------- * Function: H5E__clear_entries @@ -783,12 +831,16 @@ H5E__clear_entries(H5E_t *estack, size_t nentries) /* Decrement the IDs to indicate that they are no longer used by this stack */ /* (In reverse order that they were incremented, so that reference counts work well) */ - if (H5I_dec_ref(error->min_num) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message"); - if (H5I_dec_ref(error->maj_num) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message"); - if (H5I_dec_ref(error->cls_id) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error class"); + /* Note: don't decrement library internal error IDs, since they weren't incremented */ + if (error->min_num < H5E_first_min_id_g || error->min_num > H5E_last_min_id_g) + if (H5I_dec_ref(error->min_num) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message"); + if (error->maj_num < H5E_first_maj_id_g || error->maj_num > H5E_last_maj_id_g) + if (H5I_dec_ref(error->maj_num) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message"); + if (error->cls_id != H5E_ERR_CLS_g) + if (H5I_dec_ref(error->cls_id) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error class"); /* Release strings */ /* The 'func' & 'file' strings are statically allocated (by the compiler) @@ -880,32 +932,28 @@ H5E__pop(H5E_t *estack, size_t count) *------------------------------------------------------------------------- */ herr_t -H5E_dump_api_stack(bool is_api) +H5E_dump_api_stack(void) { + H5E_t *estack = H5E__get_my_stack(); herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOERR - /* Only dump the error stack during an API call */ - if (is_api) { - H5E_t *estack = H5E__get_my_stack(); - - assert(estack); + assert(estack); #ifdef H5_NO_DEPRECATED_SYMBOLS + if (estack->auto_op.func2) + (void)((estack->auto_op.func2)(H5E_DEFAULT, estack->auto_data)); +#else /* H5_NO_DEPRECATED_SYMBOLS */ + if (estack->auto_op.vers == 1) { + if (estack->auto_op.func1) + (void)((estack->auto_op.func1)(estack->auto_data)); + } /* end if */ + else { if (estack->auto_op.func2) (void)((estack->auto_op.func2)(H5E_DEFAULT, estack->auto_data)); -#else /* H5_NO_DEPRECATED_SYMBOLS */ - if (estack->auto_op.vers == 1) { - if (estack->auto_op.func1) - (void)((estack->auto_op.func1)(estack->auto_data)); - } /* end if */ - else { - if (estack->auto_op.func2) - (void)((estack->auto_op.func2)(H5E_DEFAULT, estack->auto_data)); - } /* end else */ + } /* end else */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ - } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5E_dump_api_stack() */ diff --git a/src/H5Epkg.h b/src/H5Epkg.h index 546e389c971..48373f4d974 100644 --- a/src/H5Epkg.h +++ b/src/H5Epkg.h @@ -117,7 +117,13 @@ struct H5E_t { * The current error stack. */ H5_DLLVAR H5E_t H5E_stack_g[1]; -#endif /* H5_HAVE_THREADSAFE */ +#endif + +/* First & last major and minor error codes registered by the library */ +H5_DLLVAR hid_t H5E_first_maj_id_g; +H5_DLLVAR hid_t H5E_last_maj_id_g; +H5_DLLVAR hid_t H5E_first_min_id_g; +H5_DLLVAR hid_t H5E_last_min_id_g; /******************************/ /* Package Private Prototypes */ @@ -126,8 +132,10 @@ H5_DLL herr_t H5E__term_deprec_interface(void); #ifdef H5_HAVE_THREADSAFE H5_DLL H5E_t *H5E__get_stack(void); #endif /* H5_HAVE_THREADSAFE */ -H5_DLL herr_t H5E__push_stack(H5E_t *estack, const char *file, const char *func, unsigned line, hid_t cls_id, - hid_t maj_id, hid_t min_id, const char *desc); +H5_DLL herr_t H5E__push_stack(H5E_t *estack, const char *file, const char *func, unsigned line, hid_t cls_id, + hid_t maj_id, hid_t min_id, const char *desc); +H5_DLL herr_t H5E__set_stack_entry(H5E_error2_t *err_entry, const char *file, const char *func, unsigned line, + hid_t cls_id, hid_t maj_id, hid_t min_id, const char *desc); H5_DLL ssize_t H5E__get_msg(const H5E_msg_t *msg_ptr, H5E_type_t *type, char *msg, size_t size); H5_DLL herr_t H5E__print(const H5E_t *estack, FILE *stream, bool bk_compat); H5_DLL herr_t H5E__walk(const H5E_t *estack, H5E_direction_t direction, const H5E_walk_op_t *op, diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h index de812f33a71..fd86e96806b 100644 --- a/src/H5Eprivate.h +++ b/src/H5Eprivate.h @@ -188,6 +188,6 @@ H5_DLL herr_t H5E_init(void); H5_DLL herr_t H5E_printf_stack(H5E_t *estack, const char *file, const char *func, unsigned line, hid_t cls_id, hid_t maj_id, hid_t min_id, const char *fmt, ...) H5_ATTR_FORMAT(printf, 8, 9); H5_DLL herr_t H5E_clear_stack(H5E_t *estack); -H5_DLL herr_t H5E_dump_api_stack(bool is_api); +H5_DLL herr_t H5E_dump_api_stack(void); #endif /* H5Eprivate_H */ diff --git a/src/H5FAcache.c b/src/H5FAcache.c index 2920dd1aaeb..ecc25e216a2 100644 --- a/src/H5FAcache.c +++ b/src/H5FAcache.c @@ -195,17 +195,19 @@ H5FA__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FARRAY, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FA__cache_hdr_verify_chksum() */ @@ -578,17 +580,19 @@ H5FA__cache_dblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FARRAY, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FA__cache_dblock_verify_chksum() */ @@ -980,17 +984,19 @@ H5FA__cache_dblk_page_verify_chksum(const void *_image, size_t len, void H5_ATTR uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FARRAY, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FA__cache_dblk_page_verify_chksum() */ diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 5f88d37668c..0819bd68f7e 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -1804,7 +1804,7 @@ H5FD__mpio_vector_build_types(uint32_t count, H5FD_mem_t types[], haddr_t addrs[ /* Determine size of this vector element */ if (!fixed_size) { if ((*s_sizes)[i] == 0) { - assert(vector_was_sorted); + assert(*vector_was_sorted); assert(i > 0); fixed_size = true; size = sizes[i - 1]; @@ -1951,7 +1951,7 @@ H5FD__mpio_vector_build_types(uint32_t count, H5FD_mem_t types[], haddr_t addrs[ done: /* free sorted vectors if they exist */ - if (!vector_was_sorted) + if (!*vector_was_sorted) if (s_types) { free(s_types); s_types = NULL; diff --git a/src/H5FL.c b/src/H5FL.c index 3415996e430..cdcdc0cbda9 100644 --- a/src/H5FL.c +++ b/src/H5FL.c @@ -113,15 +113,6 @@ struct H5FL_fac_node_t { /* The head of the list of factory things to garbage collect */ static H5FL_fac_gc_list_t H5FL_fac_gc_head = {0, NULL}; -#ifdef H5FL_TRACK - -/* Extra headers needed */ -#include "H5CSprivate.h" /* Function stack */ - -/* Head of "outstanding allocations" list */ -static H5FL_track_t *H5FL_out_head_g = NULL; -#endif /* H5FL_TRACK */ - /* Forward declarations of local static functions */ static void *H5FL__malloc(size_t mem_size); static herr_t H5FL__reg_init(H5FL_reg_head_t *head); @@ -187,25 +178,6 @@ H5FL_term_package(void) n += H5FL__arr_term(); n += H5FL__blk_term(); -#ifdef H5FL_TRACK - /* If we haven't freed all the allocated memory, dump out the list now */ - if (n > 0 && H5FL_out_head_g) { - H5FL_track_t *trk = H5FL_out_head_g; - - /* Dump information about all the outstanding allocations */ - while (trk != NULL) { - /* Print information about the outstanding block */ - fprintf(stderr, "%s: Outstanding allocation:\n", __func__); - fprintf(stderr, "\tPtr: %p, File: %s, Function: %s, Line: %d\n", - (((unsigned char *)trk) + sizeof(H5FL_track_t)), trk->file, trk->func, trk->line); - H5CS_print_stack(trk->stack, stderr); - - /* Advance to next node */ - trk = trk->next; - } /* end while */ - } /* end if */ -#endif /* H5FL_TRACK */ - FUNC_LEAVE_NOAPI(n) } /* end H5FL_term_package() */ @@ -279,11 +251,6 @@ H5FL__reg_init(H5FL_reg_head_t *head) if (head->size < sizeof(H5FL_reg_node_t)) head->size = sizeof(H5FL_reg_node_t); - /* Make certain there's room for tracking information, if any */ -#ifdef H5FL_TRACK - head->size += sizeof(H5FL_track_t); -#endif /* H5FL_TRACK */ - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL__reg_init() */ @@ -310,32 +277,6 @@ H5FL_reg_free(H5FL_reg_head_t *head, void *obj) assert(head); assert(obj); -#ifdef H5FL_TRACK - { - H5FL_track_t *trk = obj = ((unsigned char *)obj) - sizeof(H5FL_track_t); - - /* Free tracking information about the allocation location */ - H5CS_close_stack(trk->stack); - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * and are not allocated, so there's no need to free them. - */ - trk->file = NULL; - trk->func = NULL; - - /* Remove from "outstanding allocations" list */ - if (trk == H5FL_out_head_g) { - H5FL_out_head_g = H5FL_out_head_g->next; - if (H5FL_out_head_g) - H5FL_out_head_g->prev = NULL; - } /* end if */ - else { - trk->prev->next = trk->next; - if (trk->next) - trk->next->prev = trk->prev; - } /* end else */ - } -#endif /* H5FL_TRACK */ - #ifdef H5FL_DEBUG memset(obj, 255, head->size); #endif /* H5FL_DEBUG */ @@ -381,7 +322,7 @@ H5FL_reg_free(H5FL_reg_head_t *head, void *obj) *------------------------------------------------------------------------- */ void * -H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) +H5FL_reg_malloc(H5FL_reg_head_t *head) { void *ret_value = NULL; /* Pointer to object to return */ @@ -418,28 +359,6 @@ H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) head->allocated++; } /* end else */ -#ifdef H5FL_TRACK - /* Copy allocation location information */ - ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); - assert(((H5FL_track_t *)ret_value)->stack); - /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - ((H5FL_track_t *)ret_value)->file = call_file; - ((H5FL_track_t *)ret_value)->func = call_func; - ((H5FL_track_t *)ret_value)->line = call_line; - - /* Add to "outstanding allocations" list */ - ((H5FL_track_t *)ret_value)->prev = NULL; - ((H5FL_track_t *)ret_value)->next = H5FL_out_head_g; - if (H5FL_out_head_g) - H5FL_out_head_g->prev = (H5FL_track_t *)ret_value; - H5FL_out_head_g = (H5FL_track_t *)ret_value; - - /* Adjust for allocation tracking information */ - ret_value = ((unsigned char *)ret_value) + sizeof(H5FL_track_t); -#endif /* H5FL_TRACK */ - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_reg_malloc() */ @@ -455,7 +374,7 @@ H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) *------------------------------------------------------------------------- */ void * -H5FL_reg_calloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) +H5FL_reg_calloc(H5FL_reg_head_t *head) { void *ret_value = NULL; /* Pointer to object to return */ @@ -465,12 +384,11 @@ H5FL_reg_calloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) assert(head); /* Allocate the block */ - if (NULL == (ret_value = H5FL_reg_malloc(head H5FL_TRACK_INFO_INT))) + if (NULL == (ret_value = H5FL_reg_malloc(head))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Clear to zeros */ - /* (Accommodate tracking information, if present) */ - memset(ret_value, 0, head->size - H5FL_TRACK_SIZE); + memset(ret_value, 0, head->size); done: FUNC_LEAVE_NOAPI(ret_value) @@ -803,7 +721,7 @@ H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size) *------------------------------------------------------------------------- */ void * -H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) +H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size) { H5FL_blk_node_t *free_list; /* The free list of nodes of correct size */ H5FL_blk_list_t *temp; /* Temp. ptr to the new native list allocated */ @@ -844,8 +762,7 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) assert(free_list); /* Allocate new node, with room for the page info header and the actual page data */ - if (NULL == - (temp = (H5FL_blk_list_t *)H5FL__malloc(sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE + size))) + if (NULL == (temp = (H5FL_blk_list_t *)H5FL__malloc(sizeof(H5FL_blk_list_t) + size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk"); /* Increment the number of blocks of this size */ @@ -861,28 +778,6 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) /* Set the return value to the block itself */ ret_value = ((char *)temp) + sizeof(H5FL_blk_list_t); -#ifdef H5FL_TRACK - /* Copy allocation location information */ - ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); - assert(((H5FL_track_t *)ret_value)->stack); - /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - ((H5FL_track_t *)ret_value)->file = call_file; - ((H5FL_track_t *)ret_value)->func = call_func; - ((H5FL_track_t *)ret_value)->line = call_line; - - /* Add to "outstanding allocations" list */ - ((H5FL_track_t *)ret_value)->prev = NULL; - ((H5FL_track_t *)ret_value)->next = H5FL_out_head_g; - if (H5FL_out_head_g) - H5FL_out_head_g->prev = (H5FL_track_t *)ret_value; - H5FL_out_head_g = (H5FL_track_t *)ret_value; - - /* Adjust for allocation tracking information */ - ret_value = ((unsigned char *)ret_value) + sizeof(H5FL_track_t); -#endif /* H5FL_TRACK */ - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_malloc() */ @@ -902,7 +797,7 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) *------------------------------------------------------------------------- */ void * -H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) +H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size) { void *ret_value = NULL; /* Pointer to the block to return to the user */ @@ -913,7 +808,7 @@ H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) assert(size); /* Allocate the block */ - if (NULL == (ret_value = H5FL_blk_malloc(head, size H5FL_TRACK_INFO_INT))) + if (NULL == (ret_value = H5FL_blk_malloc(head, size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Clear the block to zeros */ @@ -952,46 +847,14 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block) assert(head); assert(block); -#ifdef H5FL_TRACK - { - unsigned char *block_ptr = ((unsigned char *)block) - sizeof(H5FL_track_t); - H5FL_track_t trk; - - H5MM_memcpy(&trk, block_ptr, sizeof(H5FL_track_t)); - - /* Free tracking information about the allocation location */ - H5CS_close_stack(trk.stack); - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * and are not allocated, so there's no need to free them. - */ - trk.file = NULL; - trk.func = NULL; - - /* Remove from "outstanding allocations" list */ - if ((void *)block_ptr == (void *)H5FL_out_head_g) { - H5FL_out_head_g = H5FL_out_head_g->next; - if (H5FL_out_head_g) - H5FL_out_head_g->prev = NULL; - } /* end if */ - else { - trk.prev->next = trk.next; - if (trk.next) - trk.next->prev = trk.prev; - } /* end else */ - - H5MM_memcpy(block_ptr, &trk, sizeof(H5FL_track_t)); - } -#endif /* H5FL_TRACK */ - /* Get the pointer to the native block info header in front of the native block to free */ - temp = - (H5FL_blk_list_t *)((void *)((unsigned char *)block - (sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE))); + temp = (H5FL_blk_list_t *)((void *)((unsigned char *)block - sizeof(H5FL_blk_list_t))); /* Save the block's size for later */ free_size = temp->size; #ifdef H5FL_DEBUG - memset(temp, 255, free_size + sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE); + memset(temp, 255, free_size + sizeof(H5FL_blk_list_t)); #endif /* H5FL_DEBUG */ /* Check if there is a free list for native blocks of this size */ @@ -1041,7 +904,7 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block) *------------------------------------------------------------------------- */ void * -H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size H5FL_TRACK_PARAMS) +H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size) { void *ret_value = NULL; /* Return value */ @@ -1056,54 +919,24 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size H5FL_TRACK_ H5FL_blk_list_t *temp; /* Temp. ptr to the new block node allocated */ /* Get the pointer to the chunk info header in front of the chunk to free */ - temp = (H5FL_blk_list_t *)((void *)((unsigned char *)block - - (sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE))); + temp = (H5FL_blk_list_t *)((void *)((unsigned char *)block - sizeof(H5FL_blk_list_t))); /* check if we are actually changing the size of the buffer */ if (new_size != temp->size) { size_t blk_size; /* Temporary block size */ - if ((ret_value = H5FL_blk_malloc(head, new_size H5FL_TRACK_INFO_INT)) == NULL) + if (NULL == (ret_value = H5FL_blk_malloc(head, new_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for block"); blk_size = MIN(new_size, temp->size); H5MM_memcpy(ret_value, block, blk_size); H5FL_blk_free(head, block); } /* end if */ - else { -#ifdef H5FL_TRACK - { - unsigned char *block_ptr = ((unsigned char *)block) - sizeof(H5FL_track_t); - H5FL_track_t trk; - - H5MM_memcpy(&trk, block_ptr, sizeof(H5FL_track_t)); - - /* Release previous tracking information */ - H5CS_close_stack(trk.stack); - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * and are not allocated, so there's no need to free them. - */ - trk.file = NULL; - trk.func = NULL; - - /* Store new tracking information */ - trk.stack = H5CS_copy_stack(); - assert(trk.stack); - /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - trk.file = call_file; - trk.func = call_func; - trk.line = call_line; - - H5MM_memcpy(block_ptr, &trk, sizeof(H5FL_track_t)); - } -#endif /* H5FL_TRACK */ + else ret_value = block; - } /* end if */ - } /* end if */ + } /* end if */ /* Not re-allocating, just allocate a fresh block */ else - ret_value = H5FL_blk_malloc(head, new_size H5FL_TRACK_INFO_INT); + ret_value = H5FL_blk_malloc(head, new_size); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1371,39 +1204,8 @@ H5FL_arr_free(H5FL_arr_head_t *head, void *obj) /* Make certain that the free list is initialized */ assert(head->init); -#ifdef H5FL_TRACK - { - unsigned char *block_ptr = ((unsigned char *)obj) - sizeof(H5FL_track_t); - H5FL_track_t trk; - - H5MM_memcpy(&trk, block_ptr, sizeof(H5FL_track_t)); - - /* Free tracking information about the allocation location */ - H5CS_close_stack(trk.stack); - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * and are not allocated, so there's no need to free them. - */ - trk.file = NULL; - trk.func = NULL; - - /* Remove from "outstanding allocations" list */ - if ((void *)block_ptr == H5FL_out_head_g) { - H5FL_out_head_g = H5FL_out_head_g->next; - if (H5FL_out_head_g) - H5FL_out_head_g->prev = NULL; - } /* end if */ - else { - trk.prev->next = trk.next; - if (trk.next) - trk.next->prev = trk.prev; - } /* end else */ - - H5MM_memcpy(block_ptr, &trk, sizeof(H5FL_track_t)); - } -#endif - /* Get the pointer to the info header in front of the block to free */ - temp = (H5FL_arr_list_t *)((void *)((unsigned char *)obj - (sizeof(H5FL_arr_list_t) + H5FL_TRACK_SIZE))); + temp = (H5FL_arr_list_t *)((void *)((unsigned char *)obj - sizeof(H5FL_arr_list_t))); /* Get the number of elements */ free_nelem = temp->nelem; @@ -1453,7 +1255,7 @@ H5FL_arr_free(H5FL_arr_head_t *head, void *obj) *------------------------------------------------------------------------- */ void * -H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS) +H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem) { H5FL_arr_list_t *new_obj; /* Pointer to the new free list node allocated */ size_t mem_size; /* Size of memory block being recycled */ @@ -1494,8 +1296,7 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS) } /* end if */ /* Otherwise allocate a node */ else { - if (NULL == - (new_obj = (H5FL_arr_list_t *)H5FL__malloc(sizeof(H5FL_arr_list_t) + H5FL_TRACK_SIZE + mem_size))) + if (NULL == (new_obj = (H5FL_arr_list_t *)H5FL__malloc(sizeof(H5FL_arr_list_t) + mem_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Increment the number of blocks of this size */ @@ -1511,28 +1312,6 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS) /* Get a pointer to the new block */ ret_value = ((char *)new_obj) + sizeof(H5FL_arr_list_t); -#ifdef H5FL_TRACK - /* Copy allocation location information */ - ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); - assert(((H5FL_track_t *)ret_value)->stack); - /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - ((H5FL_track_t *)ret_value)->file = call_file; - ((H5FL_track_t *)ret_value)->func = call_func; - ((H5FL_track_t *)ret_value)->line = call_line; - - /* Add to "outstanding allocations" list */ - ((H5FL_track_t *)ret_value)->prev = NULL; - ((H5FL_track_t *)ret_value)->next = H5FL_out_head_g; - if (H5FL_out_head_g) - H5FL_out_head_g->prev = (H5FL_track_t *)ret_value; - H5FL_out_head_g = (H5FL_track_t *)ret_value; - - /* Adjust for allocation tracking information */ - ret_value = ((unsigned char *)ret_value) + sizeof(H5FL_track_t); -#endif - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_arr_malloc() */ @@ -1548,7 +1327,7 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS) *------------------------------------------------------------------------- */ void * -H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS) +H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem) { void *ret_value = NULL; /* Pointer to the block to return */ @@ -1559,7 +1338,7 @@ H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS) assert(elem); /* Allocate the array */ - if (NULL == (ret_value = H5FL_arr_malloc(head, elem H5FL_TRACK_INFO_INT))) + if (NULL == (ret_value = H5FL_arr_malloc(head, elem))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Clear to zeros */ @@ -1580,7 +1359,7 @@ H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS) *------------------------------------------------------------------------- */ void * -H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PARAMS) +H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem) { void *ret_value = NULL; /* Pointer to the block to return */ @@ -1592,7 +1371,7 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PA /* Check if we are really allocating the object */ if (obj == NULL) - ret_value = H5FL_arr_malloc(head, new_elem H5FL_TRACK_INFO_INT); + ret_value = H5FL_arr_malloc(head, new_elem); else { H5FL_arr_list_t *temp; /* Temp. ptr to the new free list node allocated */ @@ -1600,15 +1379,14 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PA assert((int)new_elem <= head->maxelem); /* Get the pointer to the info header in front of the block to free */ - temp = - (H5FL_arr_list_t *)((void *)((unsigned char *)obj - (sizeof(H5FL_arr_list_t) + H5FL_TRACK_SIZE))); + temp = (H5FL_arr_list_t *)((void *)((unsigned char *)obj - sizeof(H5FL_arr_list_t))); /* Check if the size is really changing */ if (temp->nelem != new_elem) { size_t blk_size; /* Size of block */ /* Get the new array of objects */ - ret_value = H5FL_arr_malloc(head, new_elem H5FL_TRACK_INFO_INT); + ret_value = H5FL_arr_malloc(head, new_elem); /* Copy the appropriate amount of elements */ blk_size = head->list_arr[MIN(temp->nelem, new_elem)].size; @@ -1617,35 +1395,8 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PA /* Free the old block */ H5FL_arr_free(head, obj); } /* end if */ - else { -#ifdef H5FL_TRACK - unsigned char *block_ptr = ((unsigned char *)obj) - sizeof(H5FL_track_t); - H5FL_track_t trk; - - H5MM_memcpy(&trk, block_ptr, sizeof(H5FL_track_t)); - - /* Release previous tracking information */ - H5CS_close_stack(trk.stack); - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * and are not allocated, so there's no need to free them. - */ - trk.file = NULL; - trk.func = NULL; - - /* Store new tracking information */ - trk.stack = H5CS_copy_stack(); - assert(trk.stack); - /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - trk.file = call_file; - trk.func = call_func; - trk.line = call_line; - - H5MM_memcpy(block_ptr, &trk, sizeof(H5FL_track_t)); -#endif + else ret_value = obj; - } } /* end else */ FUNC_LEAVE_NOAPI(ret_value) @@ -1851,7 +1602,7 @@ H5FL_seq_free(H5FL_seq_head_t *head, void *obj) *------------------------------------------------------------------------- */ void * -H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) +H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem) { void *ret_value = NULL; /* Pointer to the block to return */ @@ -1862,7 +1613,7 @@ H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) assert(elem); /* Use block routine */ - ret_value = H5FL_blk_malloc(&(head->queue), head->size * elem H5FL_TRACK_INFO_INT); + ret_value = H5FL_blk_malloc(&(head->queue), head->size * elem); FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_seq_malloc() */ @@ -1878,7 +1629,7 @@ H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) *------------------------------------------------------------------------- */ void * -H5FL_seq_calloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) +H5FL_seq_calloc(H5FL_seq_head_t *head, size_t elem) { void *ret_value = NULL; /* Pointer to the block to return */ @@ -1889,7 +1640,7 @@ H5FL_seq_calloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) assert(elem); /* Use block routine */ - ret_value = H5FL_blk_calloc(&(head->queue), head->size * elem H5FL_TRACK_INFO_INT); + ret_value = H5FL_blk_calloc(&(head->queue), head->size * elem); FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_seq_calloc() */ @@ -1905,7 +1656,7 @@ H5FL_seq_calloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) *------------------------------------------------------------------------- */ void * -H5FL_seq_realloc(H5FL_seq_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PARAMS) +H5FL_seq_realloc(H5FL_seq_head_t *head, void *obj, size_t new_elem) { void *ret_value = NULL; /* Pointer to the block to return */ @@ -1916,7 +1667,7 @@ H5FL_seq_realloc(H5FL_seq_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PA assert(new_elem); /* Use block routine */ - ret_value = H5FL_blk_realloc(&(head->queue), obj, head->size * new_elem H5FL_TRACK_INFO_INT); + ret_value = H5FL_blk_realloc(&(head->queue), obj, head->size * new_elem); FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_seq_realloc() */ @@ -1968,11 +1719,6 @@ H5FL_fac_init(size_t size) if (factory->size < sizeof(H5FL_fac_node_t)) factory->size = sizeof(H5FL_fac_node_t); - /* Make certain there's room for tracking information, if any */ -#ifdef H5FL_TRACK - factory->size += sizeof(H5FL_track_t); -#endif /* H5FL_TRACK */ - /* Indicate that the free list is initialized */ factory->init = true; @@ -2011,32 +1757,6 @@ H5FL_fac_free(H5FL_fac_head_t *head, void *obj) assert(head); assert(obj); -#ifdef H5FL_TRACK - { - H5FL_track_t *trk = obj = ((unsigned char *)obj) - sizeof(H5FL_track_t); - - /* Free tracking information about the allocation location */ - H5CS_close_stack(trk->stack); - /* The 'func' & 'file' strings are statically allocated (by the compiler) - * and are not allocated, so there's no need to free them. - */ - trk->file = NULL; - trk->func = NULL; - - /* Remove from "outstanding allocations" list */ - if (trk == H5FL_out_head_g) { - H5FL_out_head_g = H5FL_out_head_g->next; - if (H5FL_out_head_g) - H5FL_out_head_g->prev = NULL; - } /* end if */ - else { - trk->prev->next = trk->next; - if (trk->next) - trk->next->prev = trk->prev; - } /* end else */ - } -#endif /* H5FL_TRACK */ - #ifdef H5FL_DEBUG memset(obj, 255, head->size); #endif /* H5FL_DEBUG */ @@ -2082,7 +1802,7 @@ H5FL_fac_free(H5FL_fac_head_t *head, void *obj) *------------------------------------------------------------------------- */ void * -H5FL_fac_malloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) +H5FL_fac_malloc(H5FL_fac_head_t *head) { void *ret_value = NULL; /* Pointer to the block to return */ @@ -2116,28 +1836,6 @@ H5FL_fac_malloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) head->allocated++; } /* end else */ -#ifdef H5FL_TRACK - /* Copy allocation location information */ - ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); - assert(((H5FL_track_t *)ret_value)->stack); - /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) - * there's no need to duplicate them. - */ - ((H5FL_track_t *)ret_value)->file = call_file; - ((H5FL_track_t *)ret_value)->func = call_func; - ((H5FL_track_t *)ret_value)->line = call_line; - - /* Add to "outstanding allocations" list */ - ((H5FL_track_t *)ret_value)->prev = NULL; - ((H5FL_track_t *)ret_value)->next = H5FL_out_head_g; - if (H5FL_out_head_g) - H5FL_out_head_g->prev = (H5FL_track_t *)ret_value; - H5FL_out_head_g = (H5FL_track_t *)ret_value; - - /* Adjust for allocation tracking information */ - ret_value = ((unsigned char *)ret_value) + sizeof(H5FL_track_t); -#endif /* H5FL_TRACK */ - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_fac_malloc() */ @@ -2153,7 +1851,7 @@ H5FL_fac_malloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) *------------------------------------------------------------------------- */ void * -H5FL_fac_calloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) +H5FL_fac_calloc(H5FL_fac_head_t *head) { void *ret_value = NULL; /* Pointer to the block to return */ @@ -2164,12 +1862,11 @@ H5FL_fac_calloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) assert(head); /* Allocate the block */ - if (NULL == (ret_value = H5FL_fac_malloc(head H5FL_TRACK_INFO_INT))) + if (NULL == (ret_value = H5FL_fac_malloc(head))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Clear to zeros */ - /* (Accommodate tracking information, if present) */ - memset(ret_value, 0, head->size - H5FL_TRACK_SIZE); + memset(ret_value, 0, head->size); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5FLprivate.h b/src/H5FLprivate.h index 348cfda542d..823e0fda61e 100644 --- a/src/H5FLprivate.h +++ b/src/H5FLprivate.h @@ -35,52 +35,6 @@ #define H5_NO_FAC_FREE_LISTS #endif /* H5_NO_FREE_LISTS */ -/* Macro to track location where block was allocated from */ -/* Uncomment next line to turn on tracking, but don't leave it on after - * debugging is done because of the extra overhead it imposes. - */ -/* NOTE: This hasn't been extended to all the free-list allocation routines - * yet. -QAK - */ -/* #define H5FL_TRACK */ -#ifdef H5FL_TRACK - -#ifndef H5_HAVE_CODESTACK -#error "Free list tracking requires code stack to be enabled" -#endif - -/* Macro for inclusion in the free list allocation calls */ -#define H5FL_TRACK_INFO , __FILE__, __func__, __LINE__ - -/* Macro for inclusion in internal free list allocation calls */ -#define H5FL_TRACK_INFO_INT , call_file, call_func, call_line - -/* Macro for inclusion in the free list allocation parameters */ -#define H5FL_TRACK_PARAMS , const char *call_file, const char *call_func, int call_line - -/* Forward declarations for structure fields */ -struct H5CS_t; - -/* Tracking information for each block */ -typedef struct H5FL_track_t { - struct H5CS_t *stack; /* Function stack */ - char *file; /* Name of file containing calling function */ - char *func; /* Name of calling function */ - int line; /* Line # within calling function */ - struct H5FL_track_t *next; /* Pointer to next tracking block */ - struct H5FL_track_t *prev; /* Pointer to previous tracking block */ -} H5FL_track_t; - -/* Macro for size of tracking information */ -#define H5FL_TRACK_SIZE sizeof(H5FL_track_t) - -#else /* H5FL_TRACK */ -#define H5FL_TRACK_INFO -#define H5FL_TRACK_INFO_INT -#define H5FL_TRACK_PARAMS -#define H5FL_TRACK_SIZE 0 -#endif /* H5FL_TRACK */ - /* * Private datatypes. */ @@ -118,10 +72,10 @@ typedef struct H5FL_reg_head_t { #define H5FL_DEFINE_STATIC(t) static H5FL_DEFINE_COMMON(t) /* Allocate an object of type 't' */ -#define H5FL_MALLOC(t) (t *)H5FL_reg_malloc(&(H5FL_REG_NAME(t))H5FL_TRACK_INFO) +#define H5FL_MALLOC(t) (t *)H5FL_reg_malloc(&(H5FL_REG_NAME(t))) /* Allocate an object of type 't' and clear it to all zeros */ -#define H5FL_CALLOC(t) (t *)H5FL_reg_calloc(&(H5FL_REG_NAME(t))H5FL_TRACK_INFO) +#define H5FL_CALLOC(t) (t *)H5FL_reg_calloc(&(H5FL_REG_NAME(t))) /* Free an object of type 't' */ #define H5FL_FREE(t, obj) (t *)H5FL_reg_free(&(H5FL_REG_NAME(t)), obj) @@ -189,17 +143,16 @@ typedef struct H5FL_blk_head_t { #define H5FL_BLK_DEFINE_STATIC(t) static H5FL_BLK_DEFINE_COMMON(t) /* Allocate a block of type 't' */ -#define H5FL_BLK_MALLOC(t, size) (uint8_t *)H5FL_blk_malloc(&(H5FL_BLK_NAME(t)), size H5FL_TRACK_INFO) +#define H5FL_BLK_MALLOC(t, size) (uint8_t *)H5FL_blk_malloc(&(H5FL_BLK_NAME(t)), (size)) /* Allocate a block of type 't' and clear it to zeros */ -#define H5FL_BLK_CALLOC(t, size) (uint8_t *)H5FL_blk_calloc(&(H5FL_BLK_NAME(t)), size H5FL_TRACK_INFO) +#define H5FL_BLK_CALLOC(t, size) (uint8_t *)H5FL_blk_calloc(&(H5FL_BLK_NAME(t)), (size)) /* Free a block of type 't' */ #define H5FL_BLK_FREE(t, blk) (uint8_t *)H5FL_blk_free(&(H5FL_BLK_NAME(t)), blk) /* Re-allocate a block of type 't' */ -#define H5FL_BLK_REALLOC(t, blk, new_size) \ - (uint8_t *)H5FL_blk_realloc(&(H5FL_BLK_NAME(t)), blk, new_size H5FL_TRACK_INFO) +#define H5FL_BLK_REALLOC(t, blk, new_size) (uint8_t *)H5FL_blk_realloc(&(H5FL_BLK_NAME(t)), (blk), (new_size)) /* Check if there is a free block available to reuse */ #define H5FL_BLK_AVAIL(t, size) H5FL_blk_free_block_avail(&(H5FL_BLK_NAME(t)), size) @@ -272,17 +225,16 @@ typedef struct H5FL_arr_head_t { #define H5FL_BARR_DEFINE_STATIC(b, t, m) static H5FL_ARR_DEFINE_COMMON(sizeof(b), t, m) /* Allocate an array of type 't' */ -#define H5FL_ARR_MALLOC(t, elem) H5FL_arr_malloc(&(H5FL_ARR_NAME(t)), elem H5FL_TRACK_INFO) +#define H5FL_ARR_MALLOC(t, elem) H5FL_arr_malloc(&(H5FL_ARR_NAME(t)), (elem)) /* Allocate an array of type 't' and clear it to all zeros */ -#define H5FL_ARR_CALLOC(t, elem) H5FL_arr_calloc(&(H5FL_ARR_NAME(t)), elem H5FL_TRACK_INFO) +#define H5FL_ARR_CALLOC(t, elem) H5FL_arr_calloc(&(H5FL_ARR_NAME(t)), (elem)) /* Free an array of type 't' */ #define H5FL_ARR_FREE(t, obj) (t *)H5FL_arr_free(&(H5FL_ARR_NAME(t)), obj) /* Re-allocate an array of type 't' */ -#define H5FL_ARR_REALLOC(t, obj, new_elem) \ - H5FL_arr_realloc(&(H5FL_ARR_NAME(t)), obj, new_elem H5FL_TRACK_INFO) +#define H5FL_ARR_REALLOC(t, obj, new_elem) H5FL_arr_realloc(&(H5FL_ARR_NAME(t)), obj, (new_elem)) #else /* H5_NO_ARR_FREE_LISTS */ /* Common macro for H5FL_ARR_DEFINE & H5FL_ARR_DEFINE_STATIC (and H5FL_BARR variants) */ @@ -327,17 +279,16 @@ typedef struct H5FL_seq_head_t { #define H5FL_SEQ_DEFINE_STATIC(t) static H5FL_SEQ_DEFINE_COMMON(t) /* Allocate a sequence of type 't' */ -#define H5FL_SEQ_MALLOC(t, elem) (t *)H5FL_seq_malloc(&(H5FL_SEQ_NAME(t)), elem H5FL_TRACK_INFO) +#define H5FL_SEQ_MALLOC(t, elem) (t *)H5FL_seq_malloc(&(H5FL_SEQ_NAME(t)), (elem)) /* Allocate a sequence of type 't' and clear it to all zeros */ -#define H5FL_SEQ_CALLOC(t, elem) (t *)H5FL_seq_calloc(&(H5FL_SEQ_NAME(t)), elem H5FL_TRACK_INFO) +#define H5FL_SEQ_CALLOC(t, elem) (t *)H5FL_seq_calloc(&(H5FL_SEQ_NAME(t)), (elem)) /* Free a sequence of type 't' */ #define H5FL_SEQ_FREE(t, obj) (t *)H5FL_seq_free(&(H5FL_SEQ_NAME(t)), obj) /* Re-allocate a sequence of type 't' */ -#define H5FL_SEQ_REALLOC(t, obj, new_elem) \ - (t *)H5FL_seq_realloc(&(H5FL_SEQ_NAME(t)), obj, new_elem H5FL_TRACK_INFO) +#define H5FL_SEQ_REALLOC(t, obj, new_elem) (t *)H5FL_seq_realloc(&(H5FL_SEQ_NAME(t)), obj, (new_elem)) #else /* H5_NO_SEQ_FREE_LISTS */ /* Common macro for H5FL_SEQ_DEFINE & H5FL_SEQ_DEFINE_STATIC */ @@ -375,10 +326,10 @@ typedef struct H5FL_fac_head_t { */ #ifndef H5_NO_FAC_FREE_LISTS /* Allocate a block from a factory */ -#define H5FL_FAC_MALLOC(f) H5FL_fac_malloc(f H5FL_TRACK_INFO) +#define H5FL_FAC_MALLOC(f) H5FL_fac_malloc(f) /* Allocate a block from a factory and clear it to all zeros */ -#define H5FL_FAC_CALLOC(f) H5FL_fac_calloc(f H5FL_TRACK_INFO) +#define H5FL_FAC_CALLOC(f) H5FL_fac_calloc(f) /* Return a block to a factory */ #define H5FL_FAC_FREE(f, obj) H5FL_fac_free(f, obj) @@ -393,33 +344,33 @@ typedef struct H5FL_fac_head_t { * Library prototypes. */ /* Block free lists */ -H5_DLL void *H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; -H5_DLL void *H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; +H5_DLL void *H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size) H5_ATTR_MALLOC; +H5_DLL void *H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size) H5_ATTR_MALLOC; H5_DLL void *H5FL_blk_free(H5FL_blk_head_t *head, void *block); -H5_DLL void *H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size H5FL_TRACK_PARAMS); +H5_DLL void *H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size); H5_DLL htri_t H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size); /* Regular free lists */ -H5_DLL void *H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; -H5_DLL void *H5FL_reg_calloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; +H5_DLL void *H5FL_reg_malloc(H5FL_reg_head_t *head) H5_ATTR_MALLOC; +H5_DLL void *H5FL_reg_calloc(H5FL_reg_head_t *head) H5_ATTR_MALLOC; H5_DLL void *H5FL_reg_free(H5FL_reg_head_t *head, void *obj); /* Array free lists */ -H5_DLL void *H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; -H5_DLL void *H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; +H5_DLL void *H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem) H5_ATTR_MALLOC; +H5_DLL void *H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem) H5_ATTR_MALLOC; H5_DLL void *H5FL_arr_free(H5FL_arr_head_t *head, void *obj); -H5_DLL void *H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PARAMS); +H5_DLL void *H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem); /* Sequence free lists */ -H5_DLL void *H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; -H5_DLL void *H5FL_seq_calloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; +H5_DLL void *H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem) H5_ATTR_MALLOC; +H5_DLL void *H5FL_seq_calloc(H5FL_seq_head_t *head, size_t elem) H5_ATTR_MALLOC; H5_DLL void *H5FL_seq_free(H5FL_seq_head_t *head, void *obj); -H5_DLL void *H5FL_seq_realloc(H5FL_seq_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PARAMS); +H5_DLL void *H5FL_seq_realloc(H5FL_seq_head_t *head, void *obj, size_t new_elem); /* Factory free lists */ H5_DLL H5FL_fac_head_t *H5FL_fac_init(size_t size); -H5_DLL void *H5FL_fac_malloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; -H5_DLL void *H5FL_fac_calloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) H5_ATTR_MALLOC; +H5_DLL void *H5FL_fac_malloc(H5FL_fac_head_t *head) H5_ATTR_MALLOC; +H5_DLL void *H5FL_fac_calloc(H5FL_fac_head_t *head) H5_ATTR_MALLOC; H5_DLL void *H5FL_fac_free(H5FL_fac_head_t *head, void *obj); H5_DLL herr_t H5FL_fac_term(H5FL_fac_head_t *head); diff --git a/src/H5FScache.c b/src/H5FScache.c index 3fa31f00042..7f8edf69f13 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -184,17 +184,19 @@ H5FS__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FS__cache_hdr_verify_chksum() */ @@ -887,17 +889,19 @@ H5FS__cache_sinfo_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNU uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FS__cache_sinfo_verify_chksum() */ diff --git a/src/H5Fio.c b/src/H5Fio.c index b0c24010e86..2cd8a53ba53 100644 --- a/src/H5Fio.c +++ b/src/H5Fio.c @@ -498,12 +498,18 @@ H5F__evict_cache_entries(H5F_t *f) herr_t H5F_get_checksums(const uint8_t *buf, size_t buf_size, uint32_t *s_chksum /*out*/, uint32_t *c_chksum /*out*/) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT /* Check arguments */ assert(buf); assert(buf_size); + /* Check for buffer size smaller than H5_SIZEOF_CHKSUM */ + if (buf_size < H5_SIZEOF_CHKSUM) + HGOTO_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "checksum buffer is smaller than expected"); + /* Return the stored checksum */ if (s_chksum) { const uint8_t *chk_p; /* Pointer into raw data buffer */ @@ -519,5 +525,6 @@ H5F_get_checksums(const uint8_t *buf, size_t buf_size, uint32_t *s_chksum /*out* if (c_chksum) *c_chksum = H5_checksum_metadata(buf, buf_size - H5_SIZEOF_CHKSUM, 0); - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_chksums() */ diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index db4f0c765b0..bb5b04ea1a6 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -1198,7 +1198,9 @@ H5_DLL herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id); * * \obj_id * \param[out] name Buffer for the file name - * \param[in] size Size, in bytes, of the \p name buffer + * \param[in] size The size, in bytes, of the \p name buffer. Must be the + * size of the file name in bytes plus 1 for a NULL + * terminator * * \return Returns the length of the file name if successful; otherwise returns * a negative value. @@ -1211,17 +1213,7 @@ H5_DLL herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id); * additional characters, if any, are not returned to the user * application. * - * If the length of the name, which determines the required value of - * size, is unknown, a preliminary H5Fget_name() call can be made by - * setting \p name to NULL. The return value of this call will be the - * size of the file name; that value plus one (1) can then be assigned - * to size for a second H5Fget_name() call, which will retrieve the - * actual name. (The value passed in with the parameter \p size must - * be one greater than size in bytes of the actual name in order to - * accommodate the null terminator; if \p size is set to the exact - * size of the name, the last byte passed back will contain the null - * terminator and the last character will be missing from the name - * passed back to the calling application.) + * \details_namelen{file,H5Fget_name} * * If an error occurs, the buffer pointed to by \p name is unchanged * and the function returns a negative value. diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 7161b8b2fd3..9c475ab26a2 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -371,7 +371,7 @@ H5F__cache_superblock_verify_chksum(const void *_image, size_t len, void *_udata uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE assert(image); assert(udata); @@ -380,12 +380,14 @@ H5F__cache_superblock_verify_chksum(const void *_image, size_t len, void *_udata if (udata->super_vers >= HDF5_SUPERBLOCK_VERSION_2) { /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; } +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__cache_superblock_verify_chksum() */ diff --git a/src/H5HFcache.c b/src/H5HFcache.c index 823e2dea28e..db55bf0b4d0 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -412,17 +412,19 @@ H5HF__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF__cache_hdr_verify_chksum() */ @@ -867,17 +869,19 @@ H5HF__cache_iblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF__cache_iblock_verify_chksum() */ diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index 2c10ebbc36a..d14e53dfaf9 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -243,8 +243,9 @@ H5_DLL hid_t H5Iget_file_id(hid_t id); * * \obj_id{id} * \param[out] name A buffer for the name associated with the identifier - * \param[in] size The size of the \p name buffer; usually the size of - * the name in bytes plus 1 for a NULL terminator + * \param[in] size The size, in bytes, of the \p name buffer. Must be the + * size of the object name in bytes plus 1 for a NULL + * terminator * * \return ssize_t * @@ -254,12 +255,7 @@ H5_DLL hid_t H5Iget_file_id(hid_t id); * additional characters, if any, are not returned to the user * application. * - * If the length of the name, which determines the required value of - * \p size, is unknown, a preliminary H5Iget_name() call can be made. - * The return value of this call will be the size in bytes of the - * object name. That value, plus 1 for a NULL terminator, is then - * assigned to size for a second H5Iget_name() call, which will - * retrieve the actual name. + * \details_namelen{object,H5Iget_name} * * If the object identified by \p id is an attribute, as determined * via H5Iget_type(), H5Iget_name() retrieves the name of the object diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 6916a9044c7..87f321cb986 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -190,6 +190,15 @@ H5O__cache_get_final_load_size(const void *image, size_t image_len, void *_udata /* Set the final size for the cache image */ *actual_len = udata->chunk0_size + (size_t)H5O_SIZEOF_HDR(udata->oh); + /* Save the oh version to be used later in verify_chksum callback + because oh will be freed before leaving this routine */ + udata->oh_version = udata->oh->version; + + /* Free allocated memory: fix github issue #3970 */ + if (H5O__free(udata->oh, false) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't destroy object header"); + udata->oh = NULL; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__cache_get_final_load_size() */ @@ -211,35 +220,27 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata) H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE assert(image); assert(udata); - assert(udata->oh); /* There is no checksum for version 1 */ - if (udata->oh->version != H5O_VERSION_1) { + if (udata->oh_version != H5O_VERSION_1) { uint32_t stored_chksum; /* Stored metadata checksum value */ uint32_t computed_chksum; /* Computed metadata checksum value */ /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); - - if (stored_chksum != computed_chksum) { - /* These fields are not deserialized yet in H5O__prefix_deserialize() */ - assert(udata->oh->chunk == NULL); - assert(udata->oh->mesg == NULL); - assert(udata->oh->proxy == NULL); - - /* Indicate that udata->oh is to be freed later - in H5O__prefix_deserialize() */ - udata->free_oh = true; - ret_value = false; - } + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get checksums"); + + if (stored_chksum != computed_chksum) + ret_value = false; } else assert(!(udata->common.file_intent & H5F_ACC_SWMR_WRITE)); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__cache_verify_chksum() */ @@ -275,21 +276,12 @@ H5O__cache_deserialize(const void *image, size_t len, void *_udata, bool *dirty) assert(udata->common.f); assert(udata->common.cont_msg_info); assert(dirty); + assert(udata->oh == NULL); - /* Check for partially deserialized object header - * - * The Object header prefix will be deserialized if the object header came - * through the 'get_final_load_size' callback and not deserialized if - * the object header is coming from a cache image. - */ - if (NULL == udata->oh) { - /* Deserialize the object header prefix */ - if (H5O__prefix_deserialize((const uint8_t *)image, len, udata) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't deserialize object header prefix"); - assert(udata->oh); - } + if (H5O__prefix_deserialize((const uint8_t *)image, len, udata) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't deserialize object header prefix"); + assert(udata->oh); - /* Retrieve partially deserialized object header from user data */ oh = udata->oh; /* Set SWMR flag, if appropriate */ @@ -634,7 +626,7 @@ H5O__cache_chk_verify_chksum(const void *_image, size_t len, void *_udata) H5O_chk_cache_ud_t *udata = (H5O_chk_cache_ud_t *)_udata; /* User data for callback */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE assert(image); @@ -644,12 +636,14 @@ H5O__cache_chk_verify_chksum(const void *_image, size_t len, void *_udata) uint32_t computed_chksum; /* Computed metadata checksum value */ /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; } +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__cache_chk_verify_chksum() */ @@ -1144,25 +1138,9 @@ H5O__prefix_deserialize(const uint8_t *_image, size_t len, H5O_cache_ud_t *udata if ((size_t)(image - _image) != (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh))) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "bad object header prefix length"); - /* If udata->oh is to be freed (see H5O__cache_verify_chksum), - * save the pointer to udata->oh and free it later after setting - * udata->oh with the new object header - */ - if (udata->free_oh) { - H5O_t *saved_oh = udata->oh; - assert(udata->oh); - - /* Save the object header for later use in 'deserialize' callback */ - udata->oh = oh; - if (H5O__free(saved_oh, false) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't destroy object header"); - udata->free_oh = false; - } - else - /* Save the object header for later use in 'deserialize' callback */ - udata->oh = oh; - - oh = NULL; + /* Save the object header for later use in 'deserialize' callback */ + udata->oh = oh; + oh = NULL; done: /* Release the [possibly partially initialized] object header on errors */ diff --git a/src/H5Oint.c b/src/H5Oint.c index 022ee439947..cf414a2d407 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -975,7 +975,7 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks) udata.v1_pfx_nmesgs = 0; udata.chunk0_size = 0; udata.oh = NULL; - udata.free_oh = false; + udata.oh_version = 0; udata.common.f = loc->file; udata.common.file_intent = file_intent; udata.common.merged_null_msgs = 0; diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 1803ae0daa7..ee6126a818c 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -366,7 +366,7 @@ typedef struct H5O_cache_ud_t { unsigned v1_pfx_nmesgs; /* Number of messages from v1 prefix header */ size_t chunk0_size; /* Size of serialized first chunk */ H5O_t *oh; /* Partially deserialized object header, for later use */ - bool free_oh; /* Whether to free the object header or not */ + uint8_t oh_version; /* Oh version number */ H5O_common_cache_ud_t common; /* Common object header cache callback info */ } H5O_cache_ud_t; diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 8670c0eddd3..13688ce6f15 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -6205,7 +6205,7 @@ H5_DLL herr_t H5Pget_virtual_count(hid_t dcpl_id, size_t *count /*out*/); * (0 ≤ \p index < \p count), where \p count is the * number of mappings returned by H5Pget_virtual_count(). * \param[out] name A buffer containing the name of the source dataset - * \param[in] size The size, in bytes, of the name buffer. Must be the + * \param[in] size The size, in bytes, of the \p name buffer. Must be the * size of the dataset name in bytes plus 1 for a NULL * terminator * @@ -6222,14 +6222,7 @@ H5_DLL herr_t H5Pget_virtual_count(hid_t dcpl_id, size_t *count /*out*/); * \p name; additional characters, if any, are not returned to * the user application. * - * If the length of the dataset name, which determines the - * required value of \p size, is unknown, a preliminary call - * to H5Pget_virtual_dsetname() with the last two parameters - * set to NULL and zero respectively can be made. The return - * value of this call will be the size in bytes of the dataset - * name. That value, plus 1 for a NULL terminator, must then be - * assigned to \p size for a second H5Pget_virtual_dsetname() - * call, which will retrieve the actual dataset name. + * \details_namelen{dataset,H5Pget_virtual_dsetname} * * \see_virtual * @@ -6266,14 +6259,7 @@ H5_DLL ssize_t H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, char *name / * \p name; additional characters, if any, are not returned to * the user application. * - * If the length of the filename, which determines the required - * value of \p size, is unknown, a preliminary call to - * H5Pget_virtual_filename() with the last two parameters set - * to NULL and zero respectively can be made. The return value - * of this call will be the size in bytes of the filename. That - * value, plus 1 for a NULL terminator, must then be assigned to - * \p size for a second H5Pget_virtual_filename() call, which - * will retrieve the actual filename. + * \details_namelen{file,H5Pget_virtual_filename} * * \see_virtual * diff --git a/src/H5R.c b/src/H5R.c index 1ab3711baaa..ed589801db9 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -439,7 +439,7 @@ H5Requal(const H5R_ref_t *ref1_ptr, const H5R_ref_t *ref2_ptr) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer"); /* Compare references */ - if ((ret_value = H5R__equal((const H5R_ref_priv_t *)ref2_ptr, (const H5R_ref_priv_t *)ref2_ptr)) < 0) + if ((ret_value = H5R__equal((const H5R_ref_priv_t *)ref1_ptr, (const H5R_ref_priv_t *)ref2_ptr)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOMPARE, FAIL, "cannot compare references"); done: diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index a28262c6108..53472f933ab 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -140,8 +140,9 @@ extern "C" { * \ref H5R_ref_t is defined in H5Rpublic.h as: * \snippet this H5R_ref_t_snip * - * H5Rdestroy() should be used to release the resource from the - * reference. + * The function returns a \p ref_ptr pointer, which must be released + * using H5Rdestroy() to avoid resource leaks and possible HDF5 + * library shutdown issues. * * \since 1.12.0 * @@ -178,8 +179,9 @@ H5_DLL herr_t H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5 * \ref H5R_ref_t is defined in H5Rpublic.h as: * \snippet this H5R_ref_t_snip * - * H5Rdestroy() should be used to release the resource from the - * reference. + * The function returns a \p ref_ptr pointer, which must be released + * using H5Rdestroy() to avoid resource leaks and possible HDF5 + * library shutdown issues. * * \since 1.12.0 * @@ -217,8 +219,9 @@ H5_DLL herr_t H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, h * \ref H5R_ref_t is defined in H5Rpublic.h as: * \snippet this H5R_ref_t_snip * - * H5Rdestroy() should be used to release the resource from the - * reference. + * The function returns a \p ref_ptr pointer, which must be released + * using H5Rdestroy() to avoid resource leaks and possible HDF5 + * library shutdown issues. * * \since 1.12.0 * @@ -317,6 +320,10 @@ H5_DLL htri_t H5Requal(const H5R_ref_t *ref1_ptr, const H5R_ref_t *ref2_ptr); * \p src_ref_ptr points to the reference to copy, and \p dst_ref_ptr is the * pointer to the destination reference. * + * The function returns a \p dst_ref_ptr pointer, which must be released + * using H5Rdestroy() to avoid resource leaks and possible HDF5 + * library shutdown issues. + * * \since 1.12.0 * */ @@ -512,21 +519,15 @@ H5_DLL herr_t H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *ob * * \param[in] ref_ptr Pointer to reference to query * \param[in,out] name Buffer to place the file name of the reference - * \param[in] size Size of the \p name buffer + * \param[in] size Size of the \p name buffer. When the size is passed in, + * the \c NULL terminator needs to be included. * * \return Returns the length of the name if successful, otherwise, a negative value. * * \details H5Rget_file_name() retrieves the file name for the object, * region or attribute reference pointed to by \p ref_ptr. * - * Up to \p size characters of the name are returned in \p name; - * additional characters, if any, are not returned to the user - * application. If the length of the name, which determines - * the required value of size, is unknown, a preliminary - * H5Rget_file_name() call can be made. The return value of this - * call will be the size of the file name. That value can then be - * passed in for size in the second call to H5Rget_file_name(), - * which will retrieve the actual name. + * \details_namelen{file,H5Rget_file_name} * * \since 1.12.0 * @@ -541,8 +542,9 @@ H5_DLL ssize_t H5Rget_file_name(const H5R_ref_t *ref_ptr, char *name, size_t siz * * \param[in] ref_ptr Pointer to reference to query * \rapl_id - * \param[in,out] name Buffer to place the file name of the reference - * \param[in] size Size of the \p name buffer + * \param[in,out] name Buffer to place the object name of the reference + * \param[in] size Size of the \p name buffer. When the size is passed in, + * the \c NULL terminator needs to be included. * * \return Returns the length of the name if successful, returning * 0 (zero) if no name is associated with the identifier. Otherwise @@ -556,16 +558,7 @@ H5_DLL ssize_t H5Rget_file_name(const H5R_ref_t *ref_ptr, char *name, size_t siz * be used to access external files that the reference points to * (through a file access property list). * - * Up to size characters of the name are returned in \p name; additional - * characters, if any, are not returned to the user application. If - * the length of the name, which determines the required value of - * \p size, is unknown, a preliminary call to H5Rget_obj_name() call - * can be made. The return value of this call will be the size of the - * object name. That value can then be passed in for \p size in the - * second call to H5Rget_obj_name(), which will retrieve the actual - * name. If there is no name associated with the object identifier - * or if the name is NULL, H5Rget_obj_name() returns the size of - * the name buffer (the size does not include the \c \0 terminator). + * \details_namelen{object,H5Rget_obj_name} * * If \p ref_ptr is an object reference, \p name will be returned with * a name for the referenced object. If \p ref_ptr is a dataset region @@ -596,14 +589,7 @@ H5_DLL ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *name, si * \details H5Rget_attr_name() retrieves the attribute name for the * attribute reference pointed to by \p ref_ptr. * - * Up to size characters of the name are returned in \p name; - * additional characters, if any, are not returned to the user - * application. If the length of the name, which determines - * the required value of \p size, is unknown, a preliminary - * H5Rget_attr_name() call can be made. The return value of this - * call will be the size of the attribute name. That value can then - * be passed in for size in the second call to H5Rget_attr_name(), - * which will retrieve the actual name. + * \details_namelen_plusone{attribute,H5Rget_attr_name} * * \since 1.12.0 * @@ -765,6 +751,9 @@ H5_DLL hid_t H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref) * * \return \herr_t * + * \deprecated As of HDF5-1.12, this function has been deprecated in favor of + * H5Rcreate_object(), H5Rcreate_region() and H5Rcreate_attr(). + * * \details H5Rcreate() creates the reference, \p ref, of the type specified in * \p ref_type, pointing to the object \p name located at \p loc_id. * @@ -854,6 +843,10 @@ H5_DLL herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H * \return Returns identifier of referenced object if successful; otherwise * returns a negative value. * + * \deprecated As of HDF5-1.12, this function and H5Rdereference1() have been + * deprecated in favor of H5Ropen_attr(), H5Ropen_object() + * and H5Ropen_region(). + * * \details Given a reference, \p ref, to an object or a region in an object, * H5Rdereference2() opens that object and returns an identifier. * @@ -935,6 +928,9 @@ H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); * no name is associated with the identifier. Otherwise returns a * negative value. * + * \deprecated As of HDF5-1.12, this function has been deprecated in favor of + * H5Rget_file_name(), H5Rget_obj_name() and H5Rget_attr_name(). + * * \details H5Rget_name() retrieves a name for the object identified by \p ref.\n * \p loc_id is used to identify the file containing the reference. It * can be the file identifier for the file containing the reference or @@ -952,23 +948,10 @@ H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); * reference, \p name will contain a name for the object containing the * referenced region. * - * Up to \p size characters of the name are returned in \p name; - * additional characters, if any, are not returned to the user - * application. - * - * If the length of the name, which determines the required value of \p - * size, is unknown, a preliminary H5Rget_name() call can be made. The - * return value of this call will be the size of the object name. That - * value can then be assigned to \p size for a second H5Rget_name() - * call, which will retrieve the actual name. - * - * If there is no name associated with the object identifier or if the - * \p name is \c NULL, H5Rget_name() returns the size of the \p name - * buffer (the size does not include the \p NULL terminator). + * \details_namelen{,H5Rget_name} * - * Note that an object in an HDF5 file may have multiple paths if there - * are multiple links pointing to it. This function may return any one - * of these paths. + * \note An object in an HDF5 file may have multiple paths if multiple + * links point to it. This function may return any one of these paths. * * \since 1.8.0 */ diff --git a/src/H5SMcache.c b/src/H5SMcache.c index 77f1eef222e..7bf0575ed45 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -156,17 +156,19 @@ H5SM__cache_table_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNU uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM__cache_table_verify_chksum() */ @@ -480,7 +482,7 @@ H5SM__cache_list_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, vo uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); @@ -490,11 +492,13 @@ H5SM__cache_list_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, vo chk_size = H5SM_LIST_SIZE(udata->f, udata->header->num_messages); /* Get stored and computed checksums */ - H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM__cache_list_verify_chksum() */ diff --git a/src/H5T.c b/src/H5T.c index 42cfc58c107..a386dc95a6d 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -43,6 +43,17 @@ #include "H5VLprivate.h" /* Virtual Object Layer */ #include "H5VMprivate.h" /* Vectors and arrays */ +/* Datatype conversion functions */ +#include "H5Tconv_integer.h" +#include "H5Tconv_float.h" +#include "H5Tconv_string.h" +#include "H5Tconv_bitfield.h" +#include "H5Tconv_compound.h" +#include "H5Tconv_reference.h" +#include "H5Tconv_enum.h" +#include "H5Tconv_vlen.h" +#include "H5Tconv_array.h" + /****************/ /* Local Macros */ /****************/ @@ -4470,30 +4481,6 @@ H5T_get_size(const H5T_t *dt) FUNC_LEAVE_NOAPI(dt->shared->size) } /* end H5T_get_size() */ -/*------------------------------------------------------------------------- - * Function: H5T_get_force_conv - * - * Purpose: Determines if the type has forced conversion. This will be - * true if and only if the type keeps a pointer to a file VOL - * object internally. - * - * Return: true/false (never fails) - * - *------------------------------------------------------------------------- - */ -bool -H5T_get_force_conv(const H5T_t *dt) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* check args */ - assert(dt); - assert(dt->shared); - - FUNC_LEAVE_NOAPI(dt->shared->force_conv) -} /* end H5T_get_force_conv() */ - /*------------------------------------------------------------------------- * Function: H5T_cmp * @@ -5515,7 +5502,7 @@ H5T__path_free(H5T_path_t *path, H5T_conv_ctx_t *conv_ctx) assert(conv_ctx); if (path->conv.u.app_func) { - H5T__print_stats(path, &nprint); + H5T__print_path_stats(path, &nprint); path->cdata.command = H5T_CONV_FREE; diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 3d76bd960b5..0a5e89ee99c 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -11,7 +11,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Module Info: Datatype conversions for the H5T interface. + * Module Info: General datatype conversion and conversion-related functions + * for the H5T interface. Conversion functions for specific + * datatype classes are in separate files. */ /****************/ @@ -19,1135 +21,19 @@ /****************/ #include "H5Tmodule.h" /* This source code file is part of the H5T module */ -#define H5R_FRIEND /* Suppress error about including H5Rpkg */ /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5CXprivate.h" /* API Contexts */ -#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Pprivate.h" /* Property lists */ -#include "H5Rpkg.h" /* References */ #include "H5Tpkg.h" /* Datatypes */ /****************/ /* Local Macros */ /****************/ -/* - * These macros are for the bodies of functions that convert buffers of one - * atomic type to another using hardware. - * - * They all start with `H5T_CONV_' and end with two letters that represent the - * source and destination types, respectively. The letters `s' and `S' refer to - * signed integers while the letters `u' and `U' refer to unsigned integers, and - * the letters `f' and `F' refer to floating-point values. - * - * The letter which is capitalized indicates that the corresponding type - * (source or destination) is at least as large as the other type. - * - * Certain conversions may experience overflow conditions which arise when the - * source value has a magnitude that cannot be represented by the destination - * type. - * - * Suffix Description - * ------ ----------- - * sS: Signed integers to signed integers where the destination is - * at least as wide as the source. This case cannot generate - * overflows. - * - * sU: Signed integers to unsigned integers where the destination is - * at least as wide as the source. This case experiences - * overflows when the source value is negative. - * - * uS: Unsigned integers to signed integers where the destination is - * at least as wide as the source. This case can experience - * overflows when the source and destination are the same size. - * - * uU: Unsigned integers to unsigned integers where the destination - * is at least as wide as the source. Overflows are not - * possible in this case. - * - * Ss: Signed integers to signed integers where the source is at - * least as large as the destination. Overflows can occur when - * the destination is narrower than the source. - * - * Su: Signed integers to unsigned integers where the source is at - * least as large as the destination. Overflows occur when the - * source value is negative and can also occur if the - * destination is narrower than the source. - * - * Us: Unsigned integers to signed integers where the source is at - * least as large as the destination. Overflows can occur for - * all sizes. - * - * Uu: Unsigned integers to unsigned integers where the source is at - * least as large as the destination. Overflows can occur if the - * destination is narrower than the source. - * - * su: Conversion from signed integers to unsigned integers where - * the source and destination are the same size. Overflow occurs - * when the source value is negative. - * - * us: Conversion from unsigned integers to signed integers where - * the source and destination are the same size. Overflow - * occurs when the source magnitude is too large for the - * destination. - * - * fF: Floating-point values to floating-point values where the - * destination is at least as wide as the source. This case - * cannot generate overflows. - * - * Ff: Floating-point values to floating-point values the source is at - * least as large as the destination. Overflows can occur when - * the destination is narrower than the source. - * - * xF: Integers to float-point(float or double) values where the destination - * is at least as wide as the source. This case cannot generate - * overflows. - * - * Fx: Float-point(float or double) values to integer where the source is - * at least as wide as the destination. Overflow can occur - * when the source magnitude is too large for the destination. - * - * fX: Floating-point values to integers where the destination is at least - * as wide as the source. This case cannot generate overflows. - * - * Xf: Integers to floating-point values where the source is at least as - * wide as the destination. Overflows can occur when the destination is - * narrower than the source. - * - * - * The macros take a subset of these arguments in the order listed here: - * - * CDATA: A pointer to the H5T_cdata_t structure that was passed to the - * conversion function. - * - * STYPE: The hid_t value for the source datatype. - * - * DTYPE: The hid_t value for the destination datatype. - * - * BUF: A pointer to the conversion buffer. - * - * NELMTS: The number of values to be converted. - * - * ST: The C name for source datatype (e.g., int) - * - * DT: The C name for the destination datatype (e.g., signed char) - * - * D_MIN: The minimum possible destination value. For unsigned - * destination types this should be zero. For signed - * destination types it's a negative value with a magnitude that - * is usually one greater than D_MAX. Source values which are - * smaller than D_MIN generate overflows. - * - * D_MAX: The maximum possible destination value. Source values which - * are larger than D_MAX generate overflows. - * - * The macros are implemented with a generic programming technique, similar - * to templates in C++. The macro which defines the "core" part of the - * conversion (which actually moves the data from the source to the destination) - * is invoked inside the H5T_CONV "template" macro by "gluing" it together, - * which allows the core conversion macro to be invoked as necessary. - * - * "Core" macros come in two flavors: one which calls the exception handling - * routine and one which doesn't (the "_NOEX" variant). The presence of the - * exception handling routine is detected before the loop over the values and - * the appropriate core routine loop is executed. - * - * The generic "core" macros are: (others are specific to particular conversion) - * - * Suffix Description - * ------ ----------- - * xX: Generic Conversion where the destination is at least as - * wide as the source. This case cannot generate overflows. - * - * Xx: Generic signed conversion where the source is at least as large - * as the destination. Overflows can occur when the destination is - * narrower than the source. - * - * Ux: Generic conversion for the `Us', `Uu' & `us' cases - * Overflow occurs when the source magnitude is too large for the - * destination. - * - */ -#define H5T_CONV_xX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_xX_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - *(D) = (DT)(*(S)); \ - } - -/* Added a condition branch(else if (*(S) == (DT)(D_MAX))) which seems redundant. - * It handles a special situation when the source is "float" and assigned the value - * of "INT_MAX". A compiler may do roundup making this value "INT_MAX+1". However, - * when do comparison "if (*(S) > (DT)(D_MAX))", the compiler may consider them - * equal. In this case, do not return exception but make sure the maximum is assigned - * to the destination. SLU - 2005/06/29 - */ -#define H5T_CONV_Xx_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(D_MAX); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else if (*(S) < (ST)(D_MIN)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(D_MIN); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_Xx_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX)) { \ - *(D) = (DT)(D_MAX); \ - } \ - else if (*(S) < (ST)(D_MIN)) { \ - *(D) = (DT)(D_MIN); \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } - -#define H5T_CONV_Ux_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(D_MAX); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_Ux_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX)) { \ - *(D) = (DT)(D_MAX); \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } - -#define H5T_CONV_sS(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ - H5T_CONV(H5T_CONV_xX, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_sU_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) < 0) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = 0; \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_sU_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) < 0) \ - *(D) = 0; \ - else \ - *(D) = (DT)(*(S)); \ - } - -#define H5T_CONV_sU(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ - H5T_CONV(H5T_CONV_sU, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -/* Define to 1 if overflow is possible during conversion, 0 otherwise - * Because destination is at least as wide as the source, this should only - * occur between types of equal size */ -#define H5T_CONV_uS_UCHAR_SHORT 0 -#define H5T_CONV_uS_UCHAR_INT 0 -#define H5T_CONV_uS_UCHAR_LONG 0 -#define H5T_CONV_uS_UCHAR_LLONG 0 -#if H5_SIZEOF_SHORT == H5_SIZEOF_INT -#define H5T_CONV_uS_USHORT_INT 1 -#else -#define H5T_CONV_uS_USHORT_INT 0 -#endif -#define H5T_CONV_uS_USHORT_LONG 0 -#define H5T_CONV_uS_USHORT_LLONG 0 -#if H5_SIZEOF_INT == H5_SIZEOF_LONG -#define H5T_CONV_uS_UINT_LONG 1 -#else -#define H5T_CONV_uS_UINT_LONG 0 -#endif -#define H5T_CONV_uS_UINT_LLONG 0 -#if H5_SIZEOF_LONG == H5_SIZEOF_LONG_LONG -#define H5T_CONV_uS_ULONG_LLONG 1 -#else -#define H5T_CONV_uS_ULONG_LLONG 0 -#endif - -/* Note. If an argument is stringified or concatenated, the prescan does not - * occur. To expand the macro, then stringify or concatenate its expansion, - * one macro must call another macro that does the stringification or - * concatenation. */ -#define H5T_CONV_uS_EVAL_TYPES(STYPE, DTYPE) H5_GLUE4(H5T_CONV_uS_, STYPE, _, DTYPE) - -/* Called if overflow is possible */ -#define H5T_CONV_uS_CORE_1(S, D, ST, DT, D_MIN, D_MAX) \ - if (*(S) > (DT)(D_MAX)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler */ \ - *(D) = (DT)(D_MAX); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if (except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); - -/* Called if no overflow is possible */ -#define H5T_CONV_uS_CORE_0(S, D, ST, DT, D_MIN, D_MAX) *(D) = (DT)(*(S)); - -#define H5T_CONV_uS_CORE_I(over, S, D, ST, DT, D_MIN, D_MAX) \ - H5_GLUE(H5T_CONV_uS_CORE_, over)(S, D, ST, DT, D_MIN, D_MAX) - -#define H5T_CONV_uS_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - H5T_CONV_uS_CORE_I(H5T_CONV_uS_EVAL_TYPES(STYPE, DTYPE), S, D, ST, DT, D_MIN, D_MAX) \ - } - -/* Called if overflow is possible */ -#define H5T_CONV_uS_NOEX_CORE_1(S, D, ST, DT, D_MIN, D_MAX) \ - if (*(S) > (DT)(D_MAX)) \ - *(D) = (D_MAX); \ - else \ - *(D) = (DT)(*(S)); - -/* Called if no overflow is possible */ -#define H5T_CONV_uS_NOEX_CORE_0(S, D, ST, DT, D_MIN, D_MAX) *(D) = (DT)(*(S)); - -#define H5T_CONV_uS_NOEX_CORE_I(over, S, D, ST, DT, D_MIN, D_MAX) \ - H5_GLUE(H5T_CONV_uS_NOEX_CORE_, over)(S, D, ST, DT, D_MIN, D_MAX) - -#define H5T_CONV_uS_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - H5T_CONV_uS_NOEX_CORE_I(H5T_CONV_uS_EVAL_TYPES(STYPE, DTYPE), S, D, ST, DT, D_MIN, D_MAX) \ - } - -#define H5T_CONV_uS(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ - H5T_CONV(H5T_CONV_uS, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_uU(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ - H5T_CONV(H5T_CONV_xX, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_Ss(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ - H5T_CONV(H5T_CONV_Xx, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_Su_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) < 0) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = 0; \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else if (sizeof(ST) > sizeof(DT) && *(S) > (ST)(D_MAX)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(D_MAX); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_Su_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) < 0) \ - *(D) = 0; \ - else if (sizeof(ST) > sizeof(DT) && *(S) > (ST)(D_MAX)) \ - *(D) = (DT)(D_MAX); \ - else \ - *(D) = (DT)(*(S)); \ - } - -#define H5T_CONV_Su(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ - H5T_CONV(H5T_CONV_Su, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_Us(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ - H5T_CONV(H5T_CONV_Ux, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_Uu(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ - H5T_CONV(H5T_CONV_Ux, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_su_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - /* Assumes memory format of unsigned & signed integers is same */ \ - if (*(S) < 0) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = 0; \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_su_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - /* Assumes memory format of unsigned & signed integers is same */ \ - if (*(S) < 0) \ - *(D) = 0; \ - else \ - *(D) = (DT)(*(S)); \ - } - -#define H5T_CONV_su(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) == sizeof(DT)); \ - H5T_CONV(H5T_CONV_su, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_us_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - /* Assumes memory format of unsigned & signed integers is same */ \ - if (*(S) > (ST)(D_MAX)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(D_MAX); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_us_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - /* Assumes memory format of unsigned & signed integers is same */ \ - if (*(S) > (ST)(D_MAX)) \ - *(D) = (DT)(D_MAX); \ - else \ - *(D) = (DT)(*(S)); \ - } - -#define H5T_CONV_us(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) == sizeof(DT)); \ - H5T_CONV(H5T_CONV_us, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_fF(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ - H5T_CONV(H5T_CONV_xX, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -/* Same as H5T_CONV_Xx_CORE, except that instead of using D_MAX and D_MIN - * when an overflow occurs, use the 'float' infinity values. - */ -#define H5T_CONV_Ff_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else if (*(S) < (ST)(D_MIN)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_Ff_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX)) \ - *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \ - else if (*(S) < (ST)(D_MIN)) \ - *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \ - else \ - *(D) = (DT)(*(S)); \ - } - -#define H5T_CONV_Ff(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ - H5T_CONV(H5T_CONV_Ff, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_HI_LO_BIT_SET(TYP, V, LO, HI) \ - { \ - unsigned count; \ - unsigned char p; \ - unsigned u; \ - \ - count = 0; \ - for (u = 0; u < sizeof(TYP); u++) { \ - count = (((unsigned)sizeof(TYP) - 1) - u) * 8; \ - p = (unsigned char)((V) >> count); \ - if (p > 0) { \ - if (p & 0x80) \ - count += 7; \ - else if (p & 0x40) \ - count += 6; \ - else if (p & 0x20) \ - count += 5; \ - else if (p & 0x10) \ - count += 4; \ - else if (p & 0x08) \ - count += 3; \ - else if (p & 0x04) \ - count += 2; \ - else if (p & 0x02) \ - count += 1; \ - break; \ - } /* end if */ \ - } /* end for */ \ - \ - HI = count; \ - \ - count = 0; \ - for (u = 0; u < sizeof(TYP); u++) { \ - p = (unsigned char)((V) >> (u * 8)); \ - if (p > 0) { \ - count = u * 8; \ - \ - if (p & 0x01) \ - ; \ - else if (p & 0x02) \ - count += 1; \ - else if (p & 0x04) \ - count += 2; \ - else if (p & 0x08) \ - count += 3; \ - else if (p & 0x10) \ - count += 4; \ - else if (p & 0x20) \ - count += 5; \ - else if (p & 0x40) \ - count += 6; \ - else if (p & 0x80) \ - count += 7; \ - break; \ - } /* end if */ \ - } /* end for */ \ - \ - LO = count; \ - } - -#define H5T_CONV_xF_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (sprec > dprec) { \ - unsigned low_bit_pos, high_bit_pos; \ - \ - /* Detect high & low bits set in source */ \ - H5T_HI_LO_BIT_SET(ST, *(S), low_bit_pos, high_bit_pos) \ - \ - /* Check for more bits of precision in src than available in dst */ \ - if ((high_bit_pos - low_bit_pos) >= dprec) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_PRECISION, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, \ - S, D, conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(*(S)); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_xF_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - *(D) = (DT)(*(S)); \ - } - -#define H5T_CONV_xF(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - H5T_CONV(H5T_CONV_xF, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, Y) \ - } while (0) - -/* Quincey added the condition branch (else if (*(S) != (ST)((DT)(*(S))))). - * It handles a special situation when the source is "float" and assigned the value - * of "INT_MAX". Compilers do roundup making this value "INT_MAX+1". This branch - * is to check that situation and return exception for some compilers, mainly GCC. - * The branch if (*(S) > (DT)(D_MAX) || (sprec < dprec && *(S) == - * (ST)(D_MAX))) is for some compilers like Sun, HP, IBM, and SGI where under - * the same situation the "int" doesn't overflow. SLU - 2005/9/12 - */ -#define H5T_CONV_Fx_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX) || (sprec < dprec && *(S) == (ST)(D_MAX))) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(D_MAX); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else if (*(S) < (ST)(D_MIN)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(D_MIN); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else if (*(S) != (ST)((DT)(*(S)))) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(*(S)); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_Fx_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX)) \ - *(D) = (DT)(D_MAX); \ - else if (*(S) < (ST)(D_MIN)) \ - *(D) = (DT)(D_MIN); \ - else \ - *(D) = (DT)(*(S)); \ - } - -#define H5T_CONV_Fx(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - H5T_CONV(H5T_CONV_Fx, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, Y) \ - } while (0) - -#define H5T_CONV_fX(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ - H5T_CONV(H5T_CONV_xX, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ - } while (0) - -#define H5T_CONV_Xf_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX) || (sprec < dprec && *(S) == (ST)(D_MAX))) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else if (*(S) < (ST)(D_MIN)) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ - conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else if (sprec > dprec) { \ - unsigned low_bit_pos, high_bit_pos; \ - \ - /* Detect high & low bits set in source */ \ - H5T_HI_LO_BIT_SET(ST, *(S), low_bit_pos, high_bit_pos) \ - \ - /* Check for more bits of precision in src than available in dst */ \ - if ((high_bit_pos - low_bit_pos) >= dprec) { \ - H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ - H5T_CONV_EXCEPT_PRECISION, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, \ - S, D, conv_ctx->u.conv.cb_struct.user_data); \ - if (except_ret == H5T_CONV_UNHANDLED) \ - /* Let compiler convert if case is ignored by user handler*/ \ - *(D) = (DT)(*(S)); \ - else if (except_ret == H5T_CONV_ABORT) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ - /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } \ - else \ - *(D) = (DT)(*(S)); \ - } -#define H5T_CONV_Xf_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - if (*(S) > (ST)(D_MAX)) \ - *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \ - else { \ - intmax_t s_cast = (intmax_t)(*(S)); \ - intmax_t d_cast = (intmax_t)(D_MAX); \ - \ - /* Check if source value would underflow destination. Do NOT do this \ - * by comparing against D_MIN casted to type ST here, as this will \ - * generally be undefined behavior (casting negative float value <= 1.0 \ - * to integer) for all floating point types and some compilers optimize \ - * this in a way that causes unexpected behavior. Instead, grab the \ - * absolute value of the source value first, then compare it to D_MAX. \ - */ \ - if (s_cast != INTMAX_MIN) \ - s_cast = imaxabs(s_cast); \ - else { \ - /* Handle two's complement integer representations where abs(INTMAX_MIN) \ - * can't be represented. Other representations will fall here as well, \ - * but this should be fine. \ - */ \ - s_cast = INTMAX_MAX; \ - d_cast -= 1; \ - } \ - \ - if (s_cast > d_cast) \ - *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \ - else \ - *(D) = (DT)(*(S)); \ - } \ - } - -#define H5T_CONV_Xf(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ - do { \ - HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ - H5T_CONV(H5T_CONV_Xf, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, Y) \ - } while (0) - -/* Since all "no exception" cores do the same thing (assign the value in the - * source location to the destination location, using casting), use one "core" - * to do them all. - */ -#ifndef H5_WANT_DCONV_EXCEPTION -#define H5T_CONV_NO_EXCEPT_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - { \ - *(D) = (DT)(*(S)); \ - } -#endif /* H5_WANT_DCONV_EXCEPTION */ - -/* The main part of every integer hardware conversion macro */ -#define H5T_CONV(GUTS, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, PREC) \ - { \ - herr_t ret_value = SUCCEED; /* Return value */ \ - \ - FUNC_ENTER_PACKAGE \ - \ - { \ - size_t elmtno; /*element number */ \ - H5T_CONV_DECL_PREC(PREC) /*declare precision variables, or not */ \ - void *src_buf; /*'raw' source buffer */ \ - void *dst_buf; /*'raw' destination buffer */ \ - ST *src, *s; /*source buffer */ \ - DT *dst, *d; /*destination buffer */ \ - ST src_aligned; /*source aligned type */ \ - DT dst_aligned; /*destination aligned type */ \ - bool s_mv, d_mv; /*move data to align it? */ \ - ssize_t s_stride, d_stride; /*src and dst strides */ \ - size_t safe; /*how many elements are safe to process in each pass */ \ - \ - switch (cdata->command) { \ - case H5T_CONV_INIT: \ - /* Sanity check and initialize statistics */ \ - cdata->need_bkg = H5T_BKG_NO; \ - if (NULL == st || NULL == dt) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype"); \ - if (st->shared->size != sizeof(ST) || dt->shared->size != sizeof(DT)) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "disagreement about datatype size"); \ - CI_ALLOC_PRIV \ - break; \ - \ - case H5T_CONV_FREE: \ - /* Print and free statistics */ \ - CI_PRINT_STATS(STYPE, DTYPE); \ - CI_FREE_PRIV \ - break; \ - \ - case H5T_CONV_CONV: \ - if (NULL == st || NULL == dt) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype"); \ - if (NULL == conv_ctx) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \ - "invalid datatype conversion context pointer"); \ - \ - /* Initialize source & destination strides */ \ - if (buf_stride) { \ - assert(buf_stride >= sizeof(ST)); \ - assert(buf_stride >= sizeof(DT)); \ - s_stride = d_stride = (ssize_t)buf_stride; \ - } \ - else { \ - s_stride = sizeof(ST); \ - d_stride = sizeof(DT); \ - } \ - \ - /* Is alignment required for source or dest? */ \ - s_mv = H5T_NATIVE_##STYPE##_ALIGN_g > 1 && \ - ((size_t)buf % H5T_NATIVE_##STYPE##_ALIGN_g || \ - /* Cray */ ((size_t)((ST *)buf) != (size_t)buf) || \ - (size_t)s_stride % H5T_NATIVE_##STYPE##_ALIGN_g); \ - d_mv = H5T_NATIVE_##DTYPE##_ALIGN_g > 1 && \ - ((size_t)buf % H5T_NATIVE_##DTYPE##_ALIGN_g || \ - /* Cray */ ((size_t)((DT *)buf) != (size_t)buf) || \ - (size_t)d_stride % H5T_NATIVE_##DTYPE##_ALIGN_g); \ - CI_INC_SRC(s_mv) \ - CI_INC_DST(d_mv) \ - \ - H5T_CONV_SET_PREC(PREC) /*init precision variables, or not */ \ - \ - /* The outer loop of the type conversion macro, controlling which */ \ - /* direction the buffer is walked */ \ - while (nelmts > 0) { \ - /* Check if we need to go backwards through the buffer */ \ - if (d_stride > s_stride) { \ - /* Compute the number of "safe" destination elements at */ \ - /* the end of the buffer (Those which don't overlap with */ \ - /* any source elements at the beginning of the buffer) */ \ - safe = nelmts - (((nelmts * (size_t)s_stride) + (size_t)(d_stride - 1)) / \ - (size_t)d_stride); \ - \ - /* If we're down to the last few elements, just wrap up */ \ - /* with a "real" reverse copy */ \ - if (safe < 2) { \ - src = (ST *)(src_buf = (void *)((uint8_t *)buf + \ - (nelmts - 1) * (size_t)s_stride)); \ - dst = (DT *)(dst_buf = (void *)((uint8_t *)buf + \ - (nelmts - 1) * (size_t)d_stride)); \ - s_stride = -s_stride; \ - d_stride = -d_stride; \ - \ - safe = nelmts; \ - } /* end if */ \ - else { \ - src = (ST *)(src_buf = (void *)((uint8_t *)buf + \ - (nelmts - safe) * (size_t)s_stride)); \ - dst = (DT *)(dst_buf = (void *)((uint8_t *)buf + \ - (nelmts - safe) * (size_t)d_stride)); \ - } /* end else */ \ - } /* end if */ \ - else { \ - /* Single forward pass over all data */ \ - src = (ST *)(src_buf = buf); \ - dst = (DT *)(dst_buf = buf); \ - safe = nelmts; \ - } /* end else */ \ - \ - /* Perform loop over elements to convert */ \ - if (s_mv && d_mv) { \ - /* Alignment is required for both source and dest */ \ - s = &src_aligned; \ - H5T_CONV_LOOP_OUTER(PRE_SALIGN, PRE_DALIGN, POST_SALIGN, POST_DALIGN, GUTS, \ - STYPE, DTYPE, s, d, ST, DT, D_MIN, D_MAX) \ - } \ - else if (s_mv) { \ - /* Alignment is required only for source */ \ - s = &src_aligned; \ - H5T_CONV_LOOP_OUTER(PRE_SALIGN, PRE_DNOALIGN, POST_SALIGN, POST_DNOALIGN, GUTS, \ - STYPE, DTYPE, s, dst, ST, DT, D_MIN, D_MAX) \ - } \ - else if (d_mv) { \ - /* Alignment is required only for destination */ \ - H5T_CONV_LOOP_OUTER(PRE_SNOALIGN, PRE_DALIGN, POST_SNOALIGN, POST_DALIGN, GUTS, \ - STYPE, DTYPE, src, d, ST, DT, D_MIN, D_MAX) \ - } \ - else { \ - /* Alignment is not required for both source and destination */ \ - H5T_CONV_LOOP_OUTER(PRE_SNOALIGN, PRE_DNOALIGN, POST_SNOALIGN, POST_DNOALIGN, \ - GUTS, STYPE, DTYPE, src, dst, ST, DT, D_MIN, D_MAX) \ - } \ - \ - /* Decrement number of elements left to convert */ \ - nelmts -= safe; \ - } /* end while */ \ - break; \ - \ - default: \ - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); \ - } \ - } \ - \ -done: \ - FUNC_LEAVE_NOAPI(ret_value) \ - } - -/* Declare the source & destination precision variables */ -#define H5T_CONV_DECL_PREC(PREC) H5_GLUE(H5T_CONV_DECL_PREC_, PREC) - -#define H5T_CONV_DECL_PREC_Y \ - size_t sprec; /*source precision */ \ - size_t dprec; /*destination precision */ \ - H5T_class_t tclass; /*datatype's class */ - -#define H5T_CONV_DECL_PREC_N /*no precision variables */ - -/* Initialize the source & destination precision variables */ -#define H5T_CONV_SET_PREC(PREC) H5_GLUE(H5T_CONV_SET_PREC_, PREC) - -#define H5T_CONV_SET_PREC_Y \ - /* Get source & destination precisions into a variable */ \ - tclass = st->shared->type; \ - assert(tclass == H5T_INTEGER || tclass == H5T_FLOAT); \ - if (tclass == H5T_INTEGER) \ - sprec = st->shared->u.atomic.prec; \ - else \ - sprec = 1 + st->shared->u.atomic.u.f.msize; \ - tclass = dt->shared->type; \ - assert(tclass == H5T_INTEGER || tclass == H5T_FLOAT); \ - if (tclass == H5T_INTEGER) \ - dprec = dt->shared->u.atomic.prec; \ - else \ - dprec = 1 + dt->shared->u.atomic.u.f.msize; - -#define H5T_CONV_SET_PREC_N /*don't init precision variables */ - -/* Macro defining action on source data which needs to be aligned (before main action) */ -#define H5T_CONV_LOOP_PRE_SALIGN(ST) \ - { \ - /* The uint8_t * cast is required to avoid tripping over undefined behavior. \ - * \ - * The typed pointer arrives via a void pointer, which may have any alignment. \ - * We then cast it to a pointer to a type that is assumed to be aligned, which \ - * is undefined behavior (section 6.3.2.3 paragraph 7 of the C99 standard). \ - * In the past this hasn't caused many problems, but in some cases (e.g. \ - * converting long doubles on macOS), an optimizing compiler might do the \ - * wrong thing (in the macOS case, the conversion uses SSE, which has stricter \ - * requirements about alignment). \ - */ \ - H5MM_memcpy(&src_aligned, (const uint8_t *)src, sizeof(ST)); \ - } - -/* Macro defining action on source data which doesn't need to be aligned (before main action) */ -#define H5T_CONV_LOOP_PRE_SNOALIGN(ST) \ - { \ - } - -/* Macro defining action on destination data which needs to be aligned (before main action) */ -#define H5T_CONV_LOOP_PRE_DALIGN(DT) \ - { \ - d = &dst_aligned; \ - } - -/* Macro defining action on destination data which doesn't need to be aligned (before main action) */ -#define H5T_CONV_LOOP_PRE_DNOALIGN(DT) \ - { \ - } - -/* Macro defining action on source data which needs to be aligned (after main action) */ -#define H5T_CONV_LOOP_POST_SALIGN(ST) \ - { \ - } - -/* Macro defining action on source data which doesn't need to be aligned (after main action) */ -#define H5T_CONV_LOOP_POST_SNOALIGN(ST) \ - { \ - } - -/* Macro defining action on destination data which needs to be aligned (after main action) */ -#define H5T_CONV_LOOP_POST_DALIGN(DT) \ - { \ - /* The uint8_t * cast is required to avoid tripping over undefined behavior. \ - * \ - * The typed pointer arrives via a void pointer, which may have any alignment. \ - * We then cast it to a pointer to a type that is assumed to be aligned, which \ - * is undefined behavior (section 6.3.2.3 paragraph 7 of the C99 standard). \ - * In the past this hasn't caused many problems, but in some cases (e.g. \ - * converting long doubles on macOS), an optimizing compiler might do the \ - * wrong thing (in the macOS case, the conversion uses SSE, which has stricter \ - * requirements about alignment). \ - */ \ - H5MM_memcpy((uint8_t *)dst, &dst_aligned, sizeof(DT)); \ - } - -/* Macro defining action on destination data which doesn't need to be aligned (after main action) */ -#define H5T_CONV_LOOP_POST_DNOALIGN(DT) \ - { \ - } - -/* The outer wrapper for the type conversion loop, to check for an exception handling routine */ -#define H5T_CONV_LOOP_OUTER(PRE_SALIGN_GUTS, PRE_DALIGN_GUTS, POST_SALIGN_GUTS, POST_DALIGN_GUTS, GUTS, \ - STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - if (conv_ctx->u.conv.cb_struct.func) { \ - H5T_CONV_LOOP(PRE_SALIGN_GUTS, PRE_DALIGN_GUTS, POST_SALIGN_GUTS, POST_DALIGN_GUTS, GUTS, STYPE, \ - DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - } \ - else { \ - H5T_CONV_LOOP(PRE_SALIGN_GUTS, PRE_DALIGN_GUTS, POST_SALIGN_GUTS, POST_DALIGN_GUTS, \ - H5_GLUE(GUTS, _NOEX), STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - } - -/* The inner loop of the type conversion macro, actually converting the elements */ -#define H5T_CONV_LOOP(PRE_SALIGN_GUTS, PRE_DALIGN_GUTS, POST_SALIGN_GUTS, POST_DALIGN_GUTS, GUTS, STYPE, \ - DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - for (elmtno = 0; elmtno < safe; elmtno++) { \ - /* Handle source pre-alignment */ \ - H5_GLUE(H5T_CONV_LOOP_, PRE_SALIGN_GUTS) \ - (ST) \ - \ - /* Handle destination pre-alignment */ \ - H5_GLUE(H5T_CONV_LOOP_, PRE_DALIGN_GUTS)(DT) \ - \ - /* ... user-defined stuff here -- the conversion ... */ \ - H5T_CONV_LOOP_GUTS(GUTS, STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - \ - /* Handle source post-alignment */ \ - H5_GLUE(H5T_CONV_LOOP_, POST_SALIGN_GUTS)(ST) \ - \ - /* Handle destination post-alignment */ \ - H5_GLUE(H5T_CONV_LOOP_, POST_DALIGN_GUTS)(DT) \ - \ - /* Advance pointers */ \ - src_buf = (void *)((uint8_t *)src_buf + s_stride); \ - src = (ST *)src_buf; \ - dst_buf = (void *)((uint8_t *)dst_buf + d_stride); \ - dst = (DT *)dst_buf; \ - } - -/* Macro to call the actual "guts" of the type conversion, or call the "no exception" guts */ -#ifdef H5_WANT_DCONV_EXCEPTION -#define H5T_CONV_LOOP_GUTS(GUTS, STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - /* ... user-defined stuff here -- the conversion ... */ \ - H5_GLUE(GUTS, _CORE)(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) -#else /* H5_WANT_DCONV_EXCEPTION */ -#define H5T_CONV_LOOP_GUTS(GUTS, STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ - H5_GLUE(H5T_CONV_NO_EXCEPT, _CORE)(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) -#endif /* H5_WANT_DCONV_EXCEPTION */ - -#ifdef H5T_DEBUG - -/* Print alignment statistics */ -#define CI_PRINT_STATS(STYPE, DTYPE) \ - do { \ - if (H5DEBUG(T) && ((H5T_conv_hw_t *)cdata->priv)->s_aligned) { \ - fprintf(H5DEBUG(T), " %zu src elements aligned on %zu-byte boundaries\n", \ - ((H5T_conv_hw_t *)cdata->priv)->s_aligned, H5T_NATIVE_##STYPE##_ALIGN_g); \ - } \ - if (H5DEBUG(T) && ((H5T_conv_hw_t *)cdata->priv)->d_aligned) { \ - fprintf(H5DEBUG(T), " %zu dst elements aligned on %zu-byte boundaries\n", \ - ((H5T_conv_hw_t *)cdata->priv)->d_aligned, H5T_NATIVE_##DTYPE##_ALIGN_g); \ - } \ - } while (0) - -/* Allocate private alignment structure for atomic types */ -#define CI_ALLOC_PRIV \ - if (NULL == (cdata->priv = H5MM_calloc(sizeof(H5T_conv_hw_t)))) { \ - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); \ - } - -/* Free private alignment structure for atomic types */ -#define CI_FREE_PRIV \ - if (cdata->priv != NULL) \ - cdata->priv = H5MM_xfree(cdata->priv); - -/* Increment source alignment counter */ -#define CI_INC_SRC(s) \ - if (s) \ - ((H5T_conv_hw_t *)cdata->priv)->s_aligned += nelmts; - -/* Increment destination alignment counter */ -#define CI_INC_DST(d) \ - if (d) \ - ((H5T_conv_hw_t *)cdata->priv)->d_aligned += nelmts; -#else /* H5T_DEBUG */ -#define CI_PRINT_STATS(STYPE, DTYPE) /*void*/ -#define CI_ALLOC_PRIV cdata->priv = NULL; -#define CI_FREE_PRIV /* void */ -#define CI_INC_SRC(s) /* void */ -#define CI_INC_DST(d) /* void */ -#endif /* H5T_DEBUG */ - /* Swap two elements (I & J) of an array using a temporary variable */ #define H5_SWAP_BYTES(ARRAY, I, J) \ do { \ @@ -1157,45 +43,10 @@ done: ARRAY[J] = _tmp; \ } while (0) -/* Minimum size of variable-length conversion buffer */ -#define H5T_VLEN_MIN_CONF_BUF_SIZE 4096 - /******************/ /* Local Typedefs */ /******************/ -/* Conversion data for H5T__conv_struct() */ -typedef struct H5T_conv_struct_t { - int *src2dst; /*mapping from src to dst member num */ - H5T_t **src_memb; /*source member datatypes */ - H5T_t **dst_memb; /*destination member datatypes */ - hid_t *src_memb_id; /*source member type ID's */ - hid_t *dst_memb_id; /*destination member type ID's */ - H5T_path_t **memb_path; /*conversion path for each member */ - H5T_subset_info_t subset_info; /*info related to compound subsets */ - unsigned src_nmembs; /*needed by free function */ -} H5T_conv_struct_t; - -/* Conversion data for H5T__conv_enum() */ -typedef struct H5T_conv_enum_t { - H5T_t *src_copy; /* cached copy of source datatype */ - H5T_t *dst_copy; /* cached copy of destination datatype */ - int base; /*lowest `in' value */ - unsigned length; /*num elements in arrays */ - int *src2dst; /*map from src to dst index */ -} H5T_conv_enum_t; - -/* Conversion data for H5T__conv_array() */ -typedef struct H5T_conv_array_t { - H5T_path_t *tpath; /* Conversion path for parent types */ -} H5T_conv_array_t; - -/* Conversion data for the hardware conversion functions */ -typedef struct H5T_conv_hw_t { - size_t s_aligned; /*number source elements aligned */ - size_t d_aligned; /*number destination elements aligned*/ -} H5T_conv_hw_t; - /********************/ /* Package Typedefs */ /********************/ @@ -1204,8 +55,6 @@ typedef struct H5T_conv_hw_t { /* Local Prototypes */ /********************/ -static herr_t H5T__reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order); - /*********************/ /* Public Variables */ /*********************/ @@ -1222,84 +71,314 @@ static herr_t H5T__reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_orde /* Local Variables */ /*******************/ -/* Declare a free list to manage pieces of vlen data */ -H5FL_BLK_DEFINE_STATIC(vlen_seq); - -/* Declare a free list to manage pieces of reference data */ -H5FL_BLK_DEFINE_STATIC(ref_seq); - /*------------------------------------------------------------------------- - * Function: H5T__conv_noop + * Function: H5T_reclaim * - * Purpose: The no-op conversion. The library knows about this - * conversion without it being registered. + * Purpose: Frees the buffers allocated for storing variable-length + * data in memory. Only frees the VL data in the selection + * defined in the + * dataspace. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ herr_t -H5T__conv_noop(const H5T_t H5_ATTR_UNUSED *src, const H5T_t H5_ATTR_UNUSED *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t H5_ATTR_UNUSED nelmts, - size_t H5_ATTR_UNUSED buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void H5_ATTR_UNUSED *buf, - void H5_ATTR_UNUSED *background) +H5T_reclaim(const H5T_t *type, H5S_t *space, void *buf) { - herr_t ret_value = SUCCEED; /* Return value */ + H5S_sel_iter_op_t dset_op; /* Operator for iteration */ + H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ + herr_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI_NOINIT - switch (cdata->command) { - case H5T_CONV_INIT: - cdata->need_bkg = H5T_BKG_NO; - break; + /* Check args */ + assert(type); + assert(space); + assert(buf); - case H5T_CONV_CONV: - /* Nothing to convert */ - break; + /* Get the allocation info */ + if (H5CX_get_vlen_alloc_info(&vl_alloc_info) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info"); - case H5T_CONV_FREE: - break; + /* Call H5S_select_iterate with args, etc. */ + dset_op.op_type = H5S_SEL_ITER_OP_LIB; + dset_op.u.lib_op = H5T_reclaim_cb; - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ + ret_value = H5S_select_iterate(buf, type, space, &dset_op, &vl_alloc_info); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_noop() */ +} /* end H5T_reclaim() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_order_opt - * - * Purpose: Convert one type to another when byte order is the only - * difference. This is the optimized version of H5T__conv_order() - * for a handful of different sizes. + * Function: H5T_reclaim_cb * - * Note: This is a soft conversion function. + * Purpose: Iteration callback to reclaim conversion allocated memory + * for a buffer element. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ herr_t -H5T__conv_order_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *_buf, void H5_ATTR_UNUSED *background) +H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned H5_ATTR_UNUSED ndim, const hsize_t H5_ATTR_UNUSED *point, + void *op_data) { - uint8_t *buf = (uint8_t *)_buf; - size_t i; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI_NOINIT - switch (cdata->command) { - case H5T_CONV_INIT: - /* Capability query */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || - 0 != dst->shared->u.atomic.offset) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported"); + /* Sanity check */ + assert(elem); + assert(dt); + + if (dt->shared->type == H5T_REFERENCE) { + if (H5T__ref_reclaim(elem, dt) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim ref elements"); + } + else { + assert(op_data); + + /* Allow vlen reclaim to recurse into that routine */ + if (H5T__vlen_reclaim(elem, dt, (H5T_vlen_alloc_info_t *)op_data) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim vlen elements"); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_reclaim_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5T_get_force_conv + * + * Purpose: Determines if the type has forced conversion. This will be + * true if and only if the type keeps a pointer to a file VOL + * object internally. + * + * Return: true/false (never fails) + * + *------------------------------------------------------------------------- + */ +bool +H5T_get_force_conv(const H5T_t *dt) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* check args */ + assert(dt); + assert(dt->shared); + + FUNC_LEAVE_NOAPI(dt->shared->force_conv) +} /* end H5T_get_force_conv() */ + +/*------------------------------------------------------------------------- + * Function: H5T__reverse_order + * + * Purpose: Utility function to reverse the order of a sequence of + * bytes when it's big endian or VAX order. The byte sequence + * simulates the endian order. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order) +{ + size_t i; + + FUNC_ENTER_PACKAGE_NOERR + + assert(s); + assert(size); + + if (H5T_ORDER_VAX == order) { + for (i = 0; i < size; i += 2) { + rev[i] = s[(size - 2) - i]; + rev[i + 1] = s[(size - 1) - i]; + } + } + else if (H5T_ORDER_BE == order) { + for (i = 0; i < size; i++) + rev[size - (i + 1)] = s[i]; + } + else { + for (i = 0; i < size; i++) + rev[i] = s[i]; + } + + FUNC_LEAVE_NOAPI(SUCCEED) +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_noop + * + * Purpose: The no-op conversion. The library knows about this + * conversion without it being registered. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_noop(const H5T_t H5_ATTR_UNUSED *src, const H5T_t H5_ATTR_UNUSED *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t H5_ATTR_UNUSED nelmts, + size_t H5_ATTR_UNUSED buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void H5_ATTR_UNUSED *buf, + void H5_ATTR_UNUSED *background) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_CONV: + /* Nothing to convert */ + break; + + case H5T_CONV_FREE: + break; + + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_noop() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_order + * + * Purpose: Convert one type to another when byte order is the only + * difference. + * + * Note: This is a soft conversion function. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_order(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *_buf, void H5_ATTR_UNUSED *background) +{ + uint8_t *buf = (uint8_t *)_buf; + size_t i; + size_t j, md; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* Capability query */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || + 0 != dst->shared->u.atomic.offset || + !((H5T_ORDER_BE == src->shared->u.atomic.order && + H5T_ORDER_LE == dst->shared->u.atomic.order) || + (H5T_ORDER_LE == src->shared->u.atomic.order && + H5T_ORDER_BE == dst->shared->u.atomic.order))) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported"); + switch (src->shared->type) { + case H5T_INTEGER: + case H5T_BITFIELD: + /* nothing to check */ + break; + + case H5T_FLOAT: + if (src->shared->u.atomic.u.f.sign != dst->shared->u.atomic.u.f.sign || + src->shared->u.atomic.u.f.epos != dst->shared->u.atomic.u.f.epos || + src->shared->u.atomic.u.f.esize != dst->shared->u.atomic.u.f.esize || + src->shared->u.atomic.u.f.ebias != dst->shared->u.atomic.u.f.ebias || + src->shared->u.atomic.u.f.mpos != dst->shared->u.atomic.u.f.mpos || + src->shared->u.atomic.u.f.msize != dst->shared->u.atomic.u.f.msize || + src->shared->u.atomic.u.f.norm != dst->shared->u.atomic.u.f.norm || + src->shared->u.atomic.u.f.pad != dst->shared->u.atomic.u.f.pad) { + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported"); + } /* end if */ + break; + + case H5T_NO_CLASS: + case H5T_TIME: + case H5T_STRING: + case H5T_OPAQUE: + case H5T_COMPOUND: + case H5T_REFERENCE: + case H5T_ENUM: + case H5T_VLEN: + case H5T_ARRAY: + case H5T_NCLASSES: + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported"); + } /* end switch */ + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_CONV: + /* The conversion */ + if (NULL == src) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + + buf_stride = buf_stride ? buf_stride : src->shared->size; + md = src->shared->size / 2; + for (i = 0; i < nelmts; i++, buf += buf_stride) + for (j = 0; j < md; j++) + H5_SWAP_BYTES(buf, j, src->shared->size - (j + 1)); + break; + + case H5T_CONV_FREE: + /* Free private data */ + break; + + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_order() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_order_opt + * + * Purpose: Convert one type to another when byte order is the only + * difference. This is the optimized version of H5T__conv_order() + * for a handful of different sizes. + * + * Note: This is a soft conversion function. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_order_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *_buf, void H5_ATTR_UNUSED *background) +{ + uint8_t *buf = (uint8_t *)_buf; + size_t i; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* Capability query */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || + 0 != dst->shared->u.atomic.offset) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported"); if ((src->shared->type == H5T_REFERENCE && dst->shared->type != H5T_REFERENCE) || (dst->shared->type == H5T_REFERENCE && src->shared->type != H5T_REFERENCE)) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported"); @@ -1673,8411 +752,3 @@ H5T__conv_order_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__conv_order_opt() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_order - * - * Purpose: Convert one type to another when byte order is the only - * difference. - * - * Note: This is a soft conversion function. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_order(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *_buf, void H5_ATTR_UNUSED *background) -{ - uint8_t *buf = (uint8_t *)_buf; - size_t i; - size_t j, md; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - /* Capability query */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || - 0 != dst->shared->u.atomic.offset || - !((H5T_ORDER_BE == src->shared->u.atomic.order && - H5T_ORDER_LE == dst->shared->u.atomic.order) || - (H5T_ORDER_LE == src->shared->u.atomic.order && - H5T_ORDER_BE == dst->shared->u.atomic.order))) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported"); - switch (src->shared->type) { - case H5T_INTEGER: - case H5T_BITFIELD: - /* nothing to check */ - break; - - case H5T_FLOAT: - if (src->shared->u.atomic.u.f.sign != dst->shared->u.atomic.u.f.sign || - src->shared->u.atomic.u.f.epos != dst->shared->u.atomic.u.f.epos || - src->shared->u.atomic.u.f.esize != dst->shared->u.atomic.u.f.esize || - src->shared->u.atomic.u.f.ebias != dst->shared->u.atomic.u.f.ebias || - src->shared->u.atomic.u.f.mpos != dst->shared->u.atomic.u.f.mpos || - src->shared->u.atomic.u.f.msize != dst->shared->u.atomic.u.f.msize || - src->shared->u.atomic.u.f.norm != dst->shared->u.atomic.u.f.norm || - src->shared->u.atomic.u.f.pad != dst->shared->u.atomic.u.f.pad) { - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported"); - } /* end if */ - break; - - case H5T_NO_CLASS: - case H5T_TIME: - case H5T_STRING: - case H5T_OPAQUE: - case H5T_COMPOUND: - case H5T_REFERENCE: - case H5T_ENUM: - case H5T_VLEN: - case H5T_ARRAY: - case H5T_NCLASSES: - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported"); - } /* end switch */ - cdata->need_bkg = H5T_BKG_NO; - break; - - case H5T_CONV_CONV: - /* The conversion */ - if (NULL == src) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - - buf_stride = buf_stride ? buf_stride : src->shared->size; - md = src->shared->size / 2; - for (i = 0; i < nelmts; i++, buf += buf_stride) - for (j = 0; j < md; j++) - H5_SWAP_BYTES(buf, j, src->shared->size - (j + 1)); - break; - - case H5T_CONV_FREE: - /* Free private data */ - break; - - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_order() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_b_b - * - * Purpose: Convert from one bitfield to any other bitfield. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_b_b(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *_buf, - void H5_ATTR_UNUSED *background) -{ - uint8_t *buf = (uint8_t *)_buf; - ssize_t direction; /*direction of traversal */ - size_t elmtno; /*element number */ - size_t olap; /*num overlapping elements */ - size_t half_size; /*1/2 of total size for swapping*/ - uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t dbuf[256] = {0}; /*temp destination buffer */ - size_t msb_pad_offset; /*offset for dest MSB padding */ - size_t i; - uint8_t *src_rev = NULL; /*order-reversed source buffer */ - H5T_conv_ret_t except_ret; /*return of callback function */ - bool reverse; /*if reverse the order of destination */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - /* Capability query */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (H5T_ORDER_LE != dst->shared->u.atomic.order && H5T_ORDER_BE != dst->shared->u.atomic.order) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - cdata->need_bkg = H5T_BKG_NO; - break; - - case H5T_CONV_FREE: - break; - - case H5T_CONV_CONV: - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - - /* - * Do we process the values from beginning to end or vice versa? Also, - * how many of the elements have the source and destination areas - * overlapping? - */ - if (src->shared->size == dst->shared->size || buf_stride) { - sp = dp = (uint8_t *)buf; - direction = 1; - olap = nelmts; - } - else if (src->shared->size >= dst->shared->size) { - double olap_d = - ceil((double)(dst->shared->size) / (double)(src->shared->size - dst->shared->size)); - - olap = (size_t)olap_d; - sp = dp = (uint8_t *)buf; - direction = 1; - } - else { - double olap_d = - ceil((double)(src->shared->size) / (double)(dst->shared->size - src->shared->size)); - olap = (size_t)olap_d; - sp = (uint8_t *)buf + (nelmts - 1) * src->shared->size; - dp = (uint8_t *)buf + (nelmts - 1) * dst->shared->size; - direction = -1; - } - - /* Allocate space for order-reversed source buffer */ - src_rev = (uint8_t *)H5MM_calloc(src->shared->size); - - /* The conversion loop */ - H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); - H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); - H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); - for (elmtno = 0; elmtno < nelmts; elmtno++) { - - /* - * If the source and destination buffers overlap then use a - * temporary buffer for the destination. - */ - if (direction > 0) { - s = sp; - d = elmtno < olap ? dbuf : dp; - } /* end if */ - else { - s = sp; - d = (elmtno + olap) >= nelmts ? dbuf : dp; - } /* end else */ -#ifndef NDEBUG - /* I don't quite trust the overlap calculations yet */ - if (d == dbuf) - assert((dp >= sp && dp < sp + src->shared->size) || - (sp >= dp && sp < dp + dst->shared->size)); - else - assert((dp < sp && dp + dst->shared->size <= sp) || - (sp < dp && sp + src->shared->size <= dp)); -#endif - - /* - * Put the data in little endian order so our loops aren't so - * complicated. We'll do all the conversion stuff assuming - * little endian and then we'll fix the order at the end. - */ - if (H5T_ORDER_BE == src->shared->u.atomic.order) { - half_size = src->shared->size / 2; - for (i = 0; i < half_size; i++) { - uint8_t tmp = s[src->shared->size - (i + 1)]; - s[src->shared->size - (i + 1)] = s[i]; - s[i] = tmp; - } /* end for */ - } /* end if */ - - /* Initiate these variables */ - except_ret = H5T_CONV_UNHANDLED; - reverse = true; - - /* - * Copy the significant part of the value. If the source is larger - * than the destination then invoke the overflow function or copy - * as many bits as possible. Zero extra bits in the destination. - */ - if (src->shared->u.atomic.prec > dst->shared->u.atomic.prec) { - /*overflow*/ - if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T__reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, conv_ctx->u.conv.cb_struct.user_data); - } /* end if */ - - if (except_ret == H5T_CONV_UNHANDLED) { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - dst->shared->u.atomic.prec); - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) - /*Don't reverse because user handles it*/ - reverse = false; - } - else { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - src->shared->u.atomic.prec); - H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, - dst->shared->u.atomic.prec - src->shared->u.atomic.prec, false); - } - - /* - * Fill the destination padding areas. - */ - switch (dst->shared->u.atomic.lsb_pad) { - case H5T_PAD_ZERO: - H5T__bit_set(d, (size_t)0, dst->shared->u.atomic.offset, false); - break; - - case H5T_PAD_ONE: - H5T__bit_set(d, (size_t)0, dst->shared->u.atomic.offset, true); - break; - - case H5T_PAD_ERROR: - case H5T_PAD_BACKGROUND: - case H5T_NPAD: - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported LSB padding"); - } /* end switch */ - msb_pad_offset = dst->shared->u.atomic.offset + dst->shared->u.atomic.prec; - switch (dst->shared->u.atomic.msb_pad) { - case H5T_PAD_ZERO: - H5T__bit_set(d, msb_pad_offset, 8 * dst->shared->size - msb_pad_offset, false); - break; - - case H5T_PAD_ONE: - H5T__bit_set(d, msb_pad_offset, 8 * dst->shared->size - msb_pad_offset, true); - break; - - case H5T_PAD_ERROR: - case H5T_PAD_BACKGROUND: - case H5T_NPAD: - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported MSB padding"); - } /* end switch */ - - /* - * Put the destination in the correct byte order. See note at - * beginning of loop. - */ - if (H5T_ORDER_BE == dst->shared->u.atomic.order && reverse) { - half_size = dst->shared->size / 2; - for (i = 0; i < half_size; i++) { - uint8_t tmp = d[dst->shared->size - (i + 1)]; - d[dst->shared->size - (i + 1)] = d[i]; - d[i] = tmp; - } /* end for */ - } /* end if */ - - /* - * If we had used a temporary buffer for the destination then we - * should copy the value to the true destination buffer. - */ - if (d == dbuf) - H5MM_memcpy(dp, d, dst->shared->size); - if (buf_stride) { - sp += direction * - (ssize_t)buf_stride; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ - dp += direction * - (ssize_t)buf_stride; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ - } /* end if */ - else { - sp += direction * - (ssize_t) - src->shared->size; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ - dp += direction * - (ssize_t) - dst->shared->size; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ - } /* end else */ - } /* end for */ - - break; - - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - if (src_rev) - H5MM_free(src_rev); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_b_b() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_struct_free - * - * Purpose: Free the private data structure used by the compound - * conversion functions. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -static herr_t -H5T__conv_struct_free(H5T_conv_struct_t *priv) -{ - int *src2dst = priv->src2dst; - H5T_t **src_memb = priv->src_memb; - H5T_t **dst_memb = priv->dst_memb; - hid_t *src_memb_id = priv->src_memb_id; - hid_t *dst_memb_id = priv->dst_memb_id; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_PACKAGE_NOERR - - for (unsigned i = 0; i < priv->src_nmembs; i++) - if (src2dst[i] >= 0) { - if (src_memb_id[i] >= 0) { - if (H5I_dec_ref(src_memb_id[i]) < 0) - ret_value = FAIL; /* set return value, but keep going */ - src_memb_id[i] = H5I_INVALID_HID; - src_memb[i] = NULL; - } - else { - if (H5T_close(src_memb[i]) < 0) - ret_value = FAIL; /* set return value, but keep going */ - src_memb[i] = NULL; - } - if (dst_memb_id[src2dst[i]] >= 0) { - if (H5I_dec_ref(dst_memb_id[src2dst[i]]) < 0) - ret_value = FAIL; /* set return value, but keep going */ - dst_memb_id[src2dst[i]] = H5I_INVALID_HID; - dst_memb[src2dst[i]] = NULL; - } - else { - if (H5T_close(dst_memb[src2dst[i]]) < 0) - ret_value = FAIL; /* set return value, but keep going */ - dst_memb[src2dst[i]] = NULL; - } - } /* end if */ - - H5MM_xfree(src2dst); - H5MM_xfree(src_memb); - H5MM_xfree(dst_memb); - H5MM_xfree(src_memb_id); - H5MM_xfree(dst_memb_id); - - H5MM_xfree(priv->memb_path); - H5MM_xfree(priv); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_struct_free() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_struct_init - * - * Purpose: Initialize the `priv' field of `cdata' with conversion - * information that is relatively constant. If `priv' is - * already initialized then the member conversion functions - * are recalculated. - * - * Priv fields are indexed by source member number or - * destination member number depending on whether the field - * contains information about the source datatype or the - * destination datatype (fields that contains the same - * information for both source and destination are indexed by - * source member number). The src2dst[] priv array maps source - * member numbers to destination member numbers, but if the - * source member doesn't have a corresponding destination member - * then the src2dst[i]=-1. - * - * Special optimization case when the source and destination - * members are a subset of each other, and the order is the same, - * and no conversion is needed. For example: - * struct source { struct destination { - * TYPE1 A; --> TYPE1 A; - * TYPE2 B; --> TYPE2 B; - * TYPE3 C; --> TYPE3 C; - * }; TYPE4 D; - * TYPE5 E; - * }; - * or - * struct destination { struct source { - * TYPE1 A; <-- TYPE1 A; - * TYPE2 B; <-- TYPE2 B; - * TYPE3 C; <-- TYPE3 C; - * }; TYPE4 D; - * TYPE5 E; - * }; - * The optimization is simply moving data to the appropriate - * places in the buffer. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -static herr_t -H5T__conv_struct_init(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx) -{ - H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv); - int *src2dst = NULL; - unsigned src_nmembs, dst_nmembs; - unsigned i, j; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - src_nmembs = src->shared->u.compnd.nmembs; - dst_nmembs = dst->shared->u.compnd.nmembs; - - if (!priv) { - /* - * Allocate private data structure and arrays. - */ - if (NULL == (priv = (H5T_conv_struct_t *)(cdata->priv = H5MM_calloc(sizeof(H5T_conv_struct_t))))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't allocate private conversion data"); - if (NULL == (priv->src2dst = (int *)H5MM_malloc(src_nmembs * sizeof(int)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate source to destination member mapping array"); - if (NULL == (priv->src_memb = (H5T_t **)H5MM_malloc(src_nmembs * sizeof(H5T_t *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate source compound member datatype array"); - if (NULL == (priv->dst_memb = (H5T_t **)H5MM_malloc(dst_nmembs * sizeof(H5T_t *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate destination compound member datatype array"); - - /* Allocate and initialize arrays for datatype IDs */ - if (NULL == (priv->src_memb_id = (hid_t *)H5MM_malloc(src_nmembs * sizeof(hid_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate source compound member datatype ID array"); - for (i = 0; i < src_nmembs; i++) - priv->src_memb_id[i] = H5I_INVALID_HID; - - if (NULL == (priv->dst_memb_id = (hid_t *)H5MM_malloc(dst_nmembs * sizeof(hid_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate destination compound member datatype ID array"); - for (i = 0; i < dst_nmembs; i++) - priv->dst_memb_id[i] = H5I_INVALID_HID; - - src2dst = priv->src2dst; - priv->src_nmembs = src_nmembs; - - /* The flag of special optimization to indicate if source members and destination - * members are a subset of each other. Initialize it to false */ - priv->subset_info.subset = H5T_SUBSET_FALSE; - priv->subset_info.copy_size = 0; - - /* - * Ensure that members are sorted. - */ - H5T__sort_value(src, NULL); - H5T__sort_value(dst, NULL); - - /* - * Build a mapping from source member number to destination member - * number. If some source member is not a destination member then that - * mapping element will be negative. Also create atoms for each - * source and destination member datatype if necessary. - */ - for (i = 0; i < src_nmembs; i++) { - src2dst[i] = -1; - for (j = 0; j < dst_nmembs; j++) { - if (!strcmp(src->shared->u.compnd.memb[i].name, dst->shared->u.compnd.memb[j].name)) { - H5_CHECKED_ASSIGN(src2dst[i], int, j, unsigned); - break; - } /* end if */ - } /* end for */ - if (src2dst[i] >= 0) { - H5T_t *type; - - if (NULL == (type = H5T_copy(src->shared->u.compnd.memb[i].type, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, - "can't copy source compound member datatype"); - priv->src_memb[i] = type; - - if (NULL == (type = H5T_copy(dst->shared->u.compnd.memb[src2dst[i]].type, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, - "can't copy destination compound member datatype"); - priv->dst_memb[src2dst[i]] = type; - } /* end if */ - } /* end for */ - } /* end if */ - else { - /* Restore sorted conditions for the datatypes */ - /* (Required for the src2dst array to be valid) */ - H5T__sort_value(src, NULL); - H5T__sort_value(dst, NULL); - } /* end else */ - - /* - * (Re)build the cache of member conversion functions and pointers to - * their cdata entries. - */ - src2dst = priv->src2dst; - H5MM_xfree(priv->memb_path); - if (NULL == - (priv->memb_path = (H5T_path_t **)H5MM_malloc(src->shared->u.compnd.nmembs * sizeof(H5T_path_t *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - - for (i = 0; i < src_nmembs; i++) { - if (src2dst[i] >= 0) { - H5T_path_t *tpath; - bool need_ids; - - tpath = H5T_path_find(src->shared->u.compnd.memb[i].type, - dst->shared->u.compnd.memb[src2dst[i]].type); - - if (NULL == (priv->memb_path[i] = tpath)) { - H5T__conv_struct_free(priv); - cdata->priv = NULL; - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member datatype"); - } /* end if */ - - /* Create IDs for the compound member datatypes if the conversion path uses - * an application conversion function or if a conversion exception function - * was provided. - */ - need_ids = tpath->conv.is_app || - (cdata->command == H5T_CONV_INIT && conv_ctx->u.init.cb_struct.func) || - (cdata->command == H5T_CONV_CONV && conv_ctx->u.conv.cb_struct.func); - - if (need_ids) { - hid_t tid; - - if ((tid = H5I_register(H5I_DATATYPE, priv->src_memb[i], false)) < 0) { - H5T__conv_struct_free(priv); - cdata->priv = NULL; - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, - "can't register ID for source compound member datatype"); - } - priv->src_memb_id[i] = tid; - - if ((tid = H5I_register(H5I_DATATYPE, priv->dst_memb[src2dst[i]], false)) < 0) { - H5T__conv_struct_free(priv); - cdata->priv = NULL; - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, - "can't register ID for destination compound member datatype"); - } - priv->dst_memb_id[src2dst[i]] = tid; - } - } /* end if */ - } /* end for */ - - /* The compound conversion functions need a background buffer */ - cdata->need_bkg = H5T_BKG_YES; - - if (src_nmembs < dst_nmembs) { - priv->subset_info.subset = H5T_SUBSET_SRC; - for (i = 0; i < src_nmembs; i++) { - /* If any of source members doesn't have counterpart in the same - * order or there's conversion between members, don't do the - * optimization. - */ - if (src2dst[i] != (int)i || - (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || - (priv->memb_path[i])->is_noop == false) { - priv->subset_info.subset = H5T_SUBSET_FALSE; - break; - } /* end if */ - } /* end for */ - /* Compute the size of the data to be copied for each element. It - * may be smaller than either src or dst if there is extra space at - * the end of src. - */ - if (priv->subset_info.subset == H5T_SUBSET_SRC) - priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs - 1].offset + - src->shared->u.compnd.memb[src_nmembs - 1].size; - } - else if (dst_nmembs < src_nmembs) { - priv->subset_info.subset = H5T_SUBSET_DST; - for (i = 0; i < dst_nmembs; i++) { - /* If any of source members doesn't have counterpart in the same order or - * there's conversion between members, don't do the optimization. */ - if (src2dst[i] != (int)i || - (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || - (priv->memb_path[i])->is_noop == false) { - priv->subset_info.subset = H5T_SUBSET_FALSE; - break; - } - } /* end for */ - /* Compute the size of the data to be copied for each element. It - * may be smaller than either src or dst if there is extra space at - * the end of dst. - */ - if (priv->subset_info.subset == H5T_SUBSET_DST) - priv->subset_info.copy_size = dst->shared->u.compnd.memb[dst_nmembs - 1].offset + - dst->shared->u.compnd.memb[dst_nmembs - 1].size; - } - else /* If the numbers of source and dest members are equal and no conversion is needed, - * the case should have been handled as noop earlier in H5Dio.c. */ - { - } - - cdata->recalc = false; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_struct_init() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_struct_subset - * - * Purpose: A quick way to return a field in a struct private in this - * file. The flag SMEMBS_SUBSET indicates whether the source - * members are a subset of destination or the destination - * members are a subset of the source, and the order is the - * same, and no conversion is needed. For example: - * struct source { struct destination { - * TYPE1 A; --> TYPE1 A; - * TYPE2 B; --> TYPE2 B; - * TYPE3 C; --> TYPE3 C; - * }; TYPE4 D; - * TYPE5 E; - * }; - * - * Return: A pointer to the subset info struct in p. Points directly - * into the structure. - * - *------------------------------------------------------------------------- - */ -H5T_subset_info_t * -H5T__conv_struct_subset(const H5T_cdata_t *cdata) -{ - H5T_conv_struct_t *priv = NULL; - - FUNC_ENTER_PACKAGE_NOERR - - assert(cdata); - assert(cdata->priv); - - priv = (H5T_conv_struct_t *)(cdata->priv); - - FUNC_LEAVE_NOAPI((H5T_subset_info_t *)&priv->subset_info) -} /* end H5T__conv_struct_subset() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_struct - * - * Purpose: Converts between compound datatypes. This is a soft - * conversion function. The algorithm is basically: - * - * For each element do - * For I=1..NELMTS do - * If sizeof destination type <= sizeof source type then - * Convert member to destination type; - * Move member as far left as possible; - * - * For I=NELMTS..1 do - * If not destination type then - * Convert member to destination type; - * Move member to correct position in BKG - * - * Copy BKG to BUF - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_struct(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf, void *_bkg) -{ - uint8_t *buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ - uint8_t *bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ - uint8_t *xbuf = buf, *xbkg = bkg; /*temp pointers into buf and bkg*/ - int *src2dst = NULL; /*maps src member to dst member */ - H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/ - H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */ - size_t offset; /*byte offset wrt struct */ - ssize_t src_delta; /*source stride */ - ssize_t bkg_delta; /*background stride */ - size_t elmtno; - unsigned u; /*counters */ - H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv); - H5T_conv_ctx_t tmp_conv_ctx = {0}; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - /* - * First, determine if this conversion function applies to the - * conversion path SRC-->DST. If not, return failure; - * otherwise initialize the `priv' field of `cdata' with information - * that remains (almost) constant for this conversion path. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_COMPOUND != src->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype"); - if (H5T_COMPOUND != dst->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype"); - - if (H5T__conv_struct_init(src, dst, cdata, conv_ctx) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); - break; - - case H5T_CONV_FREE: { - /* - * Free the private conversion data. - */ - herr_t status = H5T__conv_struct_free(priv); - cdata->priv = NULL; - if (status < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free private conversion data"); - - break; - } - - case H5T_CONV_CONV: - /* - * Conversion. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - assert(priv); - assert(bkg && cdata->need_bkg); - - /* Initialize temporary conversion context */ - tmp_conv_ctx = *conv_ctx; - - if (cdata->recalc && H5T__conv_struct_init(src, dst, cdata, conv_ctx) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); - - /* - * Insure that members are sorted. - */ - H5T__sort_value(src, NULL); - H5T__sort_value(dst, NULL); - src2dst = priv->src2dst; - - /* - * Direction of conversion and striding through background. - */ - if (buf_stride) { - H5_CHECKED_ASSIGN(src_delta, ssize_t, buf_stride, size_t); - if (!bkg_stride) { - H5_CHECKED_ASSIGN(bkg_delta, ssize_t, dst->shared->size, size_t); - } /* end if */ - else - H5_CHECKED_ASSIGN(bkg_delta, ssize_t, bkg_stride, size_t); - } /* end if */ - else if (dst->shared->size <= src->shared->size) { - H5_CHECKED_ASSIGN(src_delta, ssize_t, src->shared->size, size_t); - H5_CHECKED_ASSIGN(bkg_delta, ssize_t, dst->shared->size, size_t); - } /* end else-if */ - else { - H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); - src_delta = -(ssize_t)src->shared->size; - H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); - bkg_delta = -(ssize_t)dst->shared->size; - xbuf += (nelmts - 1) * src->shared->size; - xbkg += (nelmts - 1) * dst->shared->size; - } /* end else */ - - /* Conversion loop... */ - for (elmtno = 0; elmtno < nelmts; elmtno++) { - /* - * For each source member which will be present in the - * destination, convert the member to the destination type unless - * it is larger than the source type. Then move the member to the - * left-most unoccupied position in the buffer. This makes the - * data point as small as possible with all the free space on the - * right side. - */ - tmp_conv_ctx.u.conv.recursive = true; - for (u = 0, offset = 0; u < src->shared->u.compnd.nmembs; u++) { - if (src2dst[u] < 0) - continue; /*subsetting*/ - src_memb = src->shared->u.compnd.memb + u; - dst_memb = dst->shared->u.compnd.memb + src2dst[u]; - - if (dst_memb->size <= src_memb->size) { - /* Update IDs in conversion context */ - tmp_conv_ctx.u.conv.src_type_id = priv->src_memb_id[u]; - tmp_conv_ctx.u.conv.dst_type_id = priv->dst_memb_id[src2dst[u]]; - - if (H5T_convert_with_ctx(priv->memb_path[u], priv->src_memb[u], - priv->dst_memb[src2dst[u]], &tmp_conv_ctx, (size_t)1, - (size_t)0, (size_t)0, /*no striding (packed array)*/ - xbuf + src_memb->offset, xbkg + dst_memb->offset) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "unable to convert compound datatype member"); - - memmove(xbuf + offset, xbuf + src_memb->offset, dst_memb->size); - offset += dst_memb->size; - } /* end if */ - else { - memmove(xbuf + offset, xbuf + src_memb->offset, src_memb->size); - offset += src_memb->size; - } /* end else */ - } /* end for */ - tmp_conv_ctx.u.conv.recursive = false; - - /* - * For each source member which will be present in the - * destination, convert the member to the destination type if it - * is larger than the source type (that is, has not been converted - * yet). Then copy the member to the destination offset in the - * background buffer. - */ - tmp_conv_ctx.u.conv.recursive = true; - H5_CHECK_OVERFLOW(src->shared->u.compnd.nmembs, size_t, int); - for (int i = (int)src->shared->u.compnd.nmembs - 1; i >= 0; --i) { - if (src2dst[i] < 0) - continue; /*subsetting*/ - src_memb = src->shared->u.compnd.memb + i; - dst_memb = dst->shared->u.compnd.memb + src2dst[i]; - - if (dst_memb->size > src_memb->size) { - /* Update IDs in conversion context */ - tmp_conv_ctx.u.conv.src_type_id = priv->src_memb_id[i]; - tmp_conv_ctx.u.conv.dst_type_id = priv->dst_memb_id[src2dst[i]]; - - offset -= src_memb->size; - if (H5T_convert_with_ctx(priv->memb_path[i], priv->src_memb[i], - priv->dst_memb[src2dst[i]], &tmp_conv_ctx, (size_t)1, - (size_t)0, (size_t)0, /*no striding (packed array)*/ - xbuf + offset, xbkg + dst_memb->offset) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "unable to convert compound datatype member"); - } /* end if */ - else - offset -= dst_memb->size; - memcpy(xbkg + dst_memb->offset, xbuf + offset, dst_memb->size); - } /* end for */ - tmp_conv_ctx.u.conv.recursive = false; - - assert(0 == offset); - - /* - * Update pointers - */ - xbuf += src_delta; - xbkg += bkg_delta; - } /* end for */ - - /* If the bkg_delta was set to -(dst->shared->size), make it positive now */ - if (buf_stride == 0 && dst->shared->size > src->shared->size) - H5_CHECKED_ASSIGN(bkg_delta, ssize_t, dst->shared->size, size_t); - - /* - * Copy the background buffer back into the in-place conversion - * buffer. - */ - for (xbuf = buf, xbkg = bkg, elmtno = 0; elmtno < nelmts; elmtno++) { - memcpy(xbuf, xbkg, dst->shared->size); - xbuf += buf_stride ? buf_stride : dst->shared->size; - xbkg += bkg_delta; - } /* end for */ - break; - - default: - /* Some other command we don't know about yet.*/ - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_struct() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_struct_opt - * - * Purpose: Converts between compound datatypes in a manner more - * efficient than the general-purpose H5T__conv_struct() - * function. This function isn't applicable if the destination - * is larger than the source type. This is a soft conversion - * function. The algorithm is basically: - * - * For each member of the struct - * If sizeof destination type <= sizeof source type then - * Convert member to destination type for all elements - * Move memb to BKG buffer for all elements - * Else - * Move member as far left as possible for all elements - * - * For each member of the struct (in reverse order) - * If not destination type then - * Convert member to destination type for all elements - * Move member to correct position in BKG for all elements - * - * Copy BKG to BUF for all elements - * - * Special case when the source and destination members - * are a subset of each other, and the order is the same, and no - * conversion is needed. For example: - * struct source { struct destination { - * TYPE1 A; --> TYPE1 A; - * TYPE2 B; --> TYPE2 B; - * TYPE3 C; --> TYPE3 C; - * }; TYPE4 D; - * TYPE5 E; - * }; - * The optimization is simply moving data to the appropriate - * places in the buffer. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_struct_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf, void *_bkg) -{ - uint8_t *buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ - uint8_t *bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ - uint8_t *xbuf = NULL; /*temporary pointer into `buf' */ - uint8_t *xbkg = NULL; /*temporary pointer into `bkg' */ - int *src2dst = NULL; /*maps src member to dst member */ - H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/ - H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */ - size_t offset; /*byte offset wrt struct */ - size_t elmtno; /*element counter */ - size_t copy_size; /*size of element for copying */ - H5T_conv_struct_t *priv = NULL; /*private data */ - H5T_conv_ctx_t tmp_conv_ctx = {0}; /*temporary conversion context */ - bool no_stride = false; /*flag to indicate no stride */ - unsigned u; /*counters */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - /* - * First, determine if this conversion function applies to the - * conversion path SRC-->DST. If not, return failure; - * otherwise initialize the `priv' field of `cdata' with information - * that remains (almost) constant for this conversion path. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_COMPOUND != src->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype"); - if (H5T_COMPOUND != dst->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype"); - - /* Initialize data which is relatively constant */ - if (H5T__conv_struct_init(src, dst, cdata, conv_ctx) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); - priv = (H5T_conv_struct_t *)(cdata->priv); - src2dst = priv->src2dst; - - /* - * If the destination type is not larger than the source type then - * this conversion function is guaranteed to work (provided all - * members can be converted also). Otherwise the determination is - * quite a bit more complicated. Essentially we have to make sure - * that there is always room in the source buffer to do the - * conversion of a member in place. This is basically the same pair - * of loops as in the actual conversion except it checks that there - * is room for each conversion instead of actually doing anything. - */ - if (dst->shared->size > src->shared->size) { - for (u = 0, offset = 0; u < src->shared->u.compnd.nmembs; u++) { - if (src2dst[u] < 0) - continue; - src_memb = src->shared->u.compnd.memb + u; - dst_memb = dst->shared->u.compnd.memb + src2dst[u]; - if (dst_memb->size > src_memb->size) - offset += src_memb->size; - } /* end for */ - H5_CHECK_OVERFLOW(src->shared->u.compnd.nmembs, size_t, int); - for (int i = (int)src->shared->u.compnd.nmembs - 1; i >= 0; --i) { - if (src2dst[i] < 0) - continue; - src_memb = src->shared->u.compnd.memb + i; - dst_memb = dst->shared->u.compnd.memb + src2dst[i]; - if (dst_memb->size > src_memb->size) { - offset -= src_memb->size; - if (dst_memb->size > src->shared->size - offset) { - H5T__conv_struct_free(priv); - cdata->priv = NULL; - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "conversion is unsupported by this function"); - } /* end if */ - } /* end if */ - } /* end for */ - } /* end if */ - break; - - case H5T_CONV_FREE: { - /* - * Free the private conversion data. - */ - herr_t status = H5T__conv_struct_free((H5T_conv_struct_t *)(cdata->priv)); - cdata->priv = NULL; - if (status < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free private conversion data"); - - break; - } - - case H5T_CONV_CONV: - /* - * Conversion. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - if (!bkg) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid background buffer pointer"); - - /* Initialize temporary conversion context */ - tmp_conv_ctx = *conv_ctx; - - /* Update cached data if necessary */ - if (cdata->recalc && H5T__conv_struct_init(src, dst, cdata, conv_ctx) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); - priv = (H5T_conv_struct_t *)(cdata->priv); - assert(priv); - src2dst = priv->src2dst; - assert(cdata->need_bkg); - - /* - * Insure that members are sorted. - */ - H5T__sort_value(src, NULL); - H5T__sort_value(dst, NULL); - - /* - * Calculate strides. If BUF_STRIDE is non-zero then convert one - * data element at every BUF_STRIDE bytes through the main buffer - * (BUF), leaving the result of each conversion at the same - * location; otherwise assume the source and destination data are - * packed tightly based on src->shared->size and dst->shared->size. Also, if - * BUF_STRIDE and BKG_STRIDE are both non-zero then place - * background data into the BKG buffer at multiples of BKG_STRIDE; - * otherwise assume BKG buffer is the packed destination datatype. - */ - if (!buf_stride || !bkg_stride) - bkg_stride = dst->shared->size; - if (!buf_stride) { - no_stride = true; - buf_stride = src->shared->size; - } /* end if */ - - if (priv->subset_info.subset == H5T_SUBSET_SRC || priv->subset_info.subset == H5T_SUBSET_DST) { - /* If the optimization flag is set to indicate source members are a subset and - * in the top of the destination, simply copy the source members to background buffer. - */ - xbuf = buf; - xbkg = bkg; - copy_size = priv->subset_info.copy_size; - - for (elmtno = 0; elmtno < nelmts; elmtno++) { - memcpy(xbkg, xbuf, copy_size); - - /* Update pointers */ - xbuf += buf_stride; - xbkg += bkg_stride; - } /* end for */ - } /* end if */ - else { - /* - * For each member where the destination is not larger than the - * source, stride through all the elements converting only that member - * in each element and then copying the element to its final - * destination in the bkg buffer. Otherwise move the element as far - * left as possible in the buffer. - */ - tmp_conv_ctx.u.conv.recursive = true; - for (u = 0, offset = 0; u < src->shared->u.compnd.nmembs; u++) { - if (src2dst[u] < 0) - continue; /*subsetting*/ - src_memb = src->shared->u.compnd.memb + u; - dst_memb = dst->shared->u.compnd.memb + src2dst[u]; - - if (dst_memb->size <= src_memb->size) { - /* Update IDs in conversion context */ - tmp_conv_ctx.u.conv.src_type_id = priv->src_memb_id[u]; - tmp_conv_ctx.u.conv.dst_type_id = priv->dst_memb_id[src2dst[u]]; - - xbuf = buf + src_memb->offset; - xbkg = bkg + dst_memb->offset; - if (H5T_convert_with_ctx(priv->memb_path[u], priv->src_memb[u], - priv->dst_memb[src2dst[u]], &tmp_conv_ctx, nelmts, - buf_stride, bkg_stride, xbuf, xbkg) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "unable to convert compound datatype member"); - - for (elmtno = 0; elmtno < nelmts; elmtno++) { - memcpy(xbkg, xbuf, dst_memb->size); - xbuf += buf_stride; - xbkg += bkg_stride; - } /* end for */ - } /* end if */ - else { - for (xbuf = buf, elmtno = 0; elmtno < nelmts; elmtno++) { - memmove(xbuf + offset, xbuf + src_memb->offset, src_memb->size); - xbuf += buf_stride; - } /* end for */ - offset += src_memb->size; - } /* end else */ - } /* end else */ - tmp_conv_ctx.u.conv.recursive = false; - - /* - * Work from right to left, converting those members that weren't - * converted in the previous loop (those members where the destination - * is larger than the source) and them to their final position in the - * bkg buffer. - */ - tmp_conv_ctx.u.conv.recursive = true; - H5_CHECK_OVERFLOW(src->shared->u.compnd.nmembs, size_t, int); - for (int i = (int)src->shared->u.compnd.nmembs - 1; i >= 0; --i) { - if (src2dst[i] < 0) - continue; - src_memb = src->shared->u.compnd.memb + i; - dst_memb = dst->shared->u.compnd.memb + src2dst[i]; - - if (dst_memb->size > src_memb->size) { - /* Update IDs in conversion context */ - tmp_conv_ctx.u.conv.src_type_id = priv->src_memb_id[i]; - tmp_conv_ctx.u.conv.dst_type_id = priv->dst_memb_id[src2dst[i]]; - - offset -= src_memb->size; - xbuf = buf + offset; - xbkg = bkg + dst_memb->offset; - if (H5T_convert_with_ctx(priv->memb_path[i], priv->src_memb[i], - priv->dst_memb[src2dst[i]], &tmp_conv_ctx, nelmts, - buf_stride, bkg_stride, xbuf, xbkg) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "unable to convert compound datatype member"); - for (elmtno = 0; elmtno < nelmts; elmtno++) { - memcpy(xbkg, xbuf, dst_memb->size); - xbuf += buf_stride; - xbkg += bkg_stride; - } /* end for */ - } /* end if */ - } /* end for */ - tmp_conv_ctx.u.conv.recursive = false; - } /* end else */ - - if (no_stride) - buf_stride = dst->shared->size; - - /* Move background buffer into result buffer */ - for (xbuf = buf, xbkg = bkg, elmtno = 0; elmtno < nelmts; elmtno++) { - memcpy(xbuf, xbkg, dst->shared->size); - xbuf += buf_stride; - xbkg += bkg_stride; - } /* end for */ - break; - - default: - /* Some other command we don't know about yet.*/ - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_struct_opt() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_enum_free - * - * Purpose: Free the private data structure used by the enum conversion - * functions. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -static herr_t -H5T__conv_enum_free(H5T_conv_enum_t *priv) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_PACKAGE - - if (priv) { - free(priv->src2dst); - - if (priv->dst_copy && H5T_close(priv->dst_copy) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied source datatype"); - if (priv->src_copy && H5T_close(priv->src_copy) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied destination datatype"); - - free(priv); - } - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_enum_free() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_enum_init - * - * Purpose: Initialize information for H5T__conv_enum(). - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -static herr_t -H5T__conv_enum_init(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx) -{ - H5T_conv_enum_t *priv = NULL; /* Private conversion data */ - int *map = NULL; /* Map from src value to dst idx */ - bool rebuild_cache = false; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_PACKAGE - - cdata->need_bkg = H5T_BKG_NO; - - priv = (H5T_conv_enum_t *)(cdata->priv); - if (!priv) { - if (NULL == (priv = (H5T_conv_enum_t *)(cdata->priv = calloc(1, sizeof(*priv))))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - rebuild_cache = true; - } - else { - /* Check if we need to rebuild our cache. For now, treat - * enums as different even if one is just a subset of the - * other - */ - if (cdata->command == H5T_CONV_CONV && conv_ctx->u.conv.recursive) - /* Recursive conversion; we can reuse the cache */ - rebuild_cache = false; - else { - if (0 != H5T_cmp(src, priv->src_copy, false) || 0 != H5T_cmp(dst, priv->dst_copy, false)) - rebuild_cache = true; - } - } - - if (rebuild_cache) { - H5T_shared_t *src_sh; - H5T_shared_t *dst_sh; - size_t src_nmembs; - size_t dst_nmembs; - void *tmp_realloc; - - /* Allocate everything we need to cache */ - if (priv->src_copy && H5T_close(priv->src_copy) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied source datatype"); - if (priv->dst_copy && H5T_close(priv->dst_copy) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied destination datatype"); - - if (NULL == (priv->src_copy = H5T_copy(src, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy source datatype"); - if (NULL == (priv->dst_copy = H5T_copy(dst, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy destination datatype"); - - /* Nothing more to do if enum has no members */ - if (0 == src->shared->u.enumer.nmembs) - HGOTO_DONE(SUCCEED); - - src_sh = priv->src_copy->shared; - dst_sh = priv->src_copy->shared; - src_nmembs = src_sh->u.enumer.nmembs; - dst_nmembs = dst_sh->u.enumer.nmembs; - - if (NULL == (tmp_realloc = realloc(priv->src2dst, src_nmembs * sizeof(int)))) { - free(priv->src2dst); - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "unable to allocate space for source to destination enum mapping"); - } - priv->src2dst = tmp_realloc; - - /* - * Check that the source symbol names are a subset of the destination - * symbol names and build a map from source member index to destination - * member index. - */ - H5T__sort_name(priv->src_copy, NULL); - H5T__sort_name(priv->dst_copy, NULL); - for (size_t i = 0, j = 0; i < src_nmembs && j < dst_nmembs; i++, j++) { - char *src_name = src_sh->u.enumer.name[i]; - char *dst_name = dst_sh->u.enumer.name[j]; - - while (j < dst_nmembs && strcmp(src_name, dst_name) != 0) - j++; - - if (j >= dst_nmembs) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "source enum type is not a subset of destination enum type"); - - H5_CHECKED_ASSIGN(priv->src2dst[i], int, j, size_t); - } - - /* - * The conversion function will use an O(log N) lookup method for each - * value converted. However, if all of the following constraints are met - * then we can build a perfect hash table and use an O(1) lookup method. - * - * A: The source datatype size matches one of our native datatype - * sizes. - * - * B: After casting the source value bit pattern to a native type - * the size of the range of values is less than 20% larger than - * the number of values. - * - * If this special case is met then we use the source bit pattern cast as - * a native integer type as an index into the `val2dst'. The values of - * that array are the index numbers in the destination type or negative - * if the entry is unused. - * - * (This optimized algorithm doesn't work when the byte orders are different. - * The code such as "n = *((int *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * - * src_sh->size))));" can change the value significantly. i.g. if the source value is big-endian - * 0x0000000f, executing the casting on little-endian machine will get a big number 0x0f000000. Then - * it can't meet the condition "if (src_nmembs < 2 || ((double)length / (double)src_nmembs < - * (double)(1.2F)))" Because this is the optimized code, we won't fix it. It should still work in some - * situations. SLU - 2011/5/24) - */ - if (1 == src_sh->size || sizeof(short) == src_sh->size || sizeof(int) == src_sh->size) { - unsigned length; - int domain[2] = {0, 0}; /* Min and max source values */ - - for (size_t i = 0; i < src_nmembs; i++) { - int n; - - if (1 == src_sh->size) - n = *((signed char *)((uint8_t *)src_sh->u.enumer.value + i)); - else if (sizeof(short) == src_sh->size) - n = *((short *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * src_sh->size)))); - else - n = *((int *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * src_sh->size)))); - if (0 == i) { - domain[0] = domain[1] = n; - } - else { - domain[0] = MIN(domain[0], n); - domain[1] = MAX(domain[1], n); - } - } - assert(domain[1] >= domain[0]); - - length = (unsigned)(domain[1] - domain[0]) + 1; - if (src_nmembs < 2 || ((double)length / (double)src_nmembs < (double)(1.2F))) { - priv->base = domain[0]; - priv->length = length; - - if (NULL == (map = malloc(length * sizeof(int)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed"); - - for (size_t i = 0; i < length; i++) - map[i] = -1; /*entry unused*/ - - for (size_t i = 0; i < src_nmembs; i++) { - int n; - - if (1 == src_sh->size) - n = *((signed char *)((uint8_t *)src_sh->u.enumer.value + i)); - else if (sizeof(short) == src_sh->size) - n = *((short *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * src_sh->size)))); - else - n = *((int *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * src_sh->size)))); - n -= priv->base; - assert(n >= 0 && (unsigned)n < priv->length); - assert(map[n] < 0); - map[n] = priv->src2dst[i]; - } - - /* - * Replace original src2dst array with our new one. The original - * was indexed by source member number while the new one is - * indexed by source values. - */ - free(priv->src2dst); - priv->src2dst = map; - - HGOTO_DONE(SUCCEED); - } - } - - /* Sort source type by value and adjust src2dst[] appropriately */ - H5T__sort_value(priv->src_copy, priv->src2dst); - } - -#ifdef H5T_DEBUG - if (H5DEBUG(T)) { - fprintf(H5DEBUG(T), " Using %s mapping function%s\n", priv->length ? "O(1)" : "O(log N)", - priv->length ? "" : ", where N is the number of enum members"); - } -#endif - -done: - if (ret_value < 0 && priv) { - if (map) { - free(map); - priv->src2dst = NULL; - } - - if (H5T__conv_enum_free(priv) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free enum conversion data"); - - cdata->priv = NULL; - } - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_enum_init() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_enum - * - * Purpose: Converts one type of enumerated data to another. - * - * Return: Success: Non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_enum(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *_buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_conv_enum_t *priv = (H5T_conv_enum_t *)(cdata->priv); - H5T_shared_t *src_sh = NULL; - H5T_shared_t *dst_sh = NULL; - uint8_t *buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ - uint8_t *s = NULL, *d = NULL; /*src and dst BUF pointers */ - ssize_t src_delta, dst_delta; /*conversion strides */ - int n; /*src value cast as native int */ - H5T_conv_ret_t except_ret; /*return of callback function */ - size_t i; /*counters */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - /* - * Determine if this conversion function applies to the conversion - * path SRC->DST. If not return failure; otherwise initialize - * the `priv' field of `cdata' with information about the underlying - * integer conversion. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_ENUM != src->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype"); - if (H5T_ENUM != dst->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype"); - - if (H5T__conv_enum_init(src, dst, cdata, conv_ctx) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data"); - break; - - case H5T_CONV_FREE: { - herr_t status = H5T__conv_enum_free(priv); - cdata->priv = NULL; - if (status < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free private conversion data"); - - break; - } - - case H5T_CONV_CONV: - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - if (H5T_ENUM != src->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype"); - if (H5T_ENUM != dst->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype"); - - /* Reuse cache if possible, rebuild otherwise */ - if (H5T__conv_enum_init(src, dst, cdata, conv_ctx) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data"); - - src_sh = priv->src_copy->shared; - dst_sh = priv->dst_copy->shared; - - /* - * Direction of conversion. - */ - if (buf_stride) { - H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); - src_delta = dst_delta = (ssize_t)buf_stride; - s = d = buf; - } - else if (dst_sh->size <= src_sh->size) { - H5_CHECKED_ASSIGN(src_delta, ssize_t, src_sh->size, size_t); - H5_CHECKED_ASSIGN(dst_delta, ssize_t, dst_sh->size, size_t); - s = d = buf; - } - else { - H5_CHECK_OVERFLOW(src_sh->size, size_t, ssize_t); - H5_CHECK_OVERFLOW(dst_sh->size, size_t, ssize_t); - src_delta = -(ssize_t)src_sh->size; - dst_delta = -(ssize_t)dst_sh->size; - s = buf + (nelmts - 1) * src_sh->size; - d = buf + (nelmts - 1) * dst_sh->size; - } - - if (priv->length) { - for (i = 0; i < nelmts; i++, s += src_delta, d += dst_delta) { - /* Use O(1) lookup */ - /* (The casting won't work when the byte orders are different. i.g. if the source value - * is big-endian 0x0000000f, the direct casting "n = *((int *)((void *)s));" will make - * it a big number 0x0f000000 on little-endian machine. But we won't fix it because it's - * an optimization code. Please also see the comment in the H5T__conv_enum_init() - * function. SLU - 2011/5/24) - */ - if (1 == src_sh->size) - n = *((signed char *)s); - else if (sizeof(short) == src_sh->size) - n = *((short *)((void *)s)); - else - n = *((int *)((void *)s)); - n -= priv->base; - if (n < 0 || (unsigned)n >= priv->length || priv->src2dst[n] < 0) { - /*overflow*/ - except_ret = H5T_CONV_UNHANDLED; - /*If user's exception handler is present, use it*/ - if (conv_ctx->u.conv.cb_struct.func) - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, s, d, conv_ctx->u.conv.cb_struct.user_data); - - if (except_ret == H5T_CONV_UNHANDLED) - memset(d, 0xff, dst_sh->size); - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - } - else - H5MM_memcpy(d, - (uint8_t *)dst_sh->u.enumer.value + - ((unsigned)priv->src2dst[n] * dst_sh->size), - dst_sh->size); - } - } - else { - for (i = 0; i < nelmts; i++, s += src_delta, d += dst_delta) { - /* Use O(log N) lookup */ - unsigned lt = 0; - unsigned rt = src_sh->u.enumer.nmembs; - unsigned md = 0; - int cmp; - - while (lt < rt) { - md = (lt + rt) / 2; - cmp = - memcmp(s, (uint8_t *)src_sh->u.enumer.value + (md * src_sh->size), src_sh->size); - if (cmp < 0) - rt = md; - else if (cmp > 0) - lt = md + 1; - else - break; - } /* end while */ - if (lt >= rt) { - except_ret = H5T_CONV_UNHANDLED; - /*If user's exception handler is present, use it*/ - if (conv_ctx->u.conv.cb_struct.func) - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, s, d, conv_ctx->u.conv.cb_struct.user_data); - - if (except_ret == H5T_CONV_UNHANDLED) - memset(d, 0xff, dst_sh->size); - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - } /* end if */ - else { - assert(priv->src2dst[md] >= 0); - H5MM_memcpy(d, - (uint8_t *)dst_sh->u.enumer.value + - ((unsigned)priv->src2dst[md] * dst_sh->size), - dst_sh->size); - } /* end else */ - } - } - - break; - - default: - /* Some other command we don't know about yet.*/ - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_enum() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_enum_numeric - * - * Purpose: Converts enumerated data to a numeric type (integer or - * floating-point number). This function is registered into - * the conversion table twice in H5T_init_interface in H5T.c. - * Once for enum-integer conversion. Once for enum-float conversion. - * - * Return: Success: Non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_enum_numeric(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, - size_t H5_ATTR_UNUSED buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *_buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_t *src_parent; /*parent type for src */ - H5T_path_t *tpath; /* Conversion information */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - /* - * Determine if this conversion function applies to the conversion - * path SRC->DST. If not, return failure. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_ENUM != src->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "source type is not a H5T_ENUM datatype"); - if (H5T_INTEGER != dst->shared->type && H5T_FLOAT != dst->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "destination is not an integer type"); - - cdata->need_bkg = H5T_BKG_NO; - break; - - case H5T_CONV_FREE: - break; - - case H5T_CONV_CONV: - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - - src_parent = src->shared->parent; - - if (NULL == (tpath = H5T_path_find(src_parent, dst))) { - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "unable to convert between src and dest datatype"); - } - else if (!H5T_path_noop(tpath)) { - /* Convert the data */ - if (H5T_convert(tpath, src_parent, dst, nelmts, buf_stride, bkg_stride, _buf, bkg) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed"); - } - break; - - default: - /* Some other command we don't know about yet.*/ - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_enum_numeric() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_vlen_nested_free - * - * Purpose: Recursively locates and frees any nested VLEN components of - * complex data types (including COMPOUND). - * - * Return: Non-negative on success/Negative on failure. - * - *------------------------------------------------------------------------- - */ -static herr_t -H5T__conv_vlen_nested_free(uint8_t *buf, H5T_t *dt) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (dt->shared->type) { - case H5T_VLEN: - /* Pointer buf refers to VLEN data; free it (always reset tmp) */ - if ((*(dt->shared->u.vlen.cls->del))(dt->shared->u.vlen.file, buf) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free nested vlen"); - break; - - case H5T_COMPOUND: - /* Pointer buf refers to COMPOUND data; recurse for each member. */ - for (unsigned i = 0; i < dt->shared->u.compnd.nmembs; ++i) - if (H5T__conv_vlen_nested_free(buf + dt->shared->u.compnd.memb[i].offset, - dt->shared->u.compnd.memb[i].type) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free compound member"); - break; - - case H5T_ARRAY: - /* Pointer buf refers to ARRAY data; recurse for each element. */ - for (unsigned i = 0; i < dt->shared->u.array.nelem; ++i) - if (H5T__conv_vlen_nested_free(buf + i * dt->shared->parent->shared->size, - dt->shared->parent) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free array data"); - break; - - case H5T_INTEGER: - case H5T_FLOAT: - case H5T_TIME: - case H5T_STRING: - case H5T_BITFIELD: - case H5T_OPAQUE: - case H5T_REFERENCE: - case H5T_ENUM: - /* These types cannot contain vl data */ - break; - - case H5T_NO_CLASS: - case H5T_NCLASSES: - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid datatype class"); - } - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5T__conv_vlen_nested_free() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_vlen - * - * Purpose: Converts between VL datatypes in memory and on disk. - * This is a soft conversion function. The algorithm is - * basically: - * - * For every VL struct in the main buffer: - * 1. Allocate space for temporary dst VL data (reuse buffer - * if possible) - * 2. Copy VL data from src buffer into dst buffer - * 3. Convert VL data into dst representation - * 4. Allocate buffer in dst heap - * 5. Free heap objects storing old data - * 6. Write dst VL data into dst heap - * 7. Store (heap ID or pointer) and length in main dst buffer - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_vlen(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg) -{ - H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ - H5T_conv_ctx_t tmp_conv_ctx = {0}; /* Temporary conversion context */ - H5T_path_t *tpath = NULL; /* Type conversion path */ - bool noop_conv = false; /* Flag to indicate a noop conversion */ - bool write_to_file = false; /* Flag to indicate writing to file */ - htri_t parent_is_vlen; /* Flag to indicate parent is vlen datatype */ - size_t bg_seq_len = 0; /* The number of elements in the background sequence */ - H5T_t *tsrc_cpy = NULL; /* Temporary copy of source base datatype */ - H5T_t *tdst_cpy = NULL; /* Temporary copy of destination base datatype */ - hid_t tsrc_id = H5I_INVALID_HID; /* Temporary type atom */ - hid_t tdst_id = H5I_INVALID_HID; /* Temporary type atom */ - uint8_t *s = NULL; /* Source buffer */ - uint8_t *d = NULL; /* Destination buffer */ - uint8_t *b = NULL; /* Background buffer */ - ssize_t s_stride = 0; /* Src stride */ - ssize_t d_stride = 0; /* Dst stride */ - ssize_t b_stride; /* Bkg stride */ - size_t safe = 0; /* How many elements are safe to process in each pass */ - size_t src_base_size; /* Source base size*/ - size_t dst_base_size; /* Destination base size*/ - void *conv_buf = NULL; /* Temporary conversion buffer */ - size_t conv_buf_size = 0; /* Size of conversion buffer in bytes */ - void *tmp_buf = NULL; /* Temporary background buffer */ - size_t tmp_buf_size = 0; /* Size of temporary bkg buffer */ - bool nested = false; /* Flag of nested VL case */ - size_t elmtno = 0; /* Element number counter */ - size_t orig_d_stride = 0; /* Original destination stride (used for error handling) */ - size_t orig_nelmts = nelmts; /* Original # of elements to convert (used for error handling) */ - bool convert_forward = - true; /* Current direction of conversion (forward or backward, used for error handling) */ - bool conversions_made = - false; /* Flag to indicate conversions have been performed, used for error handling */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - /* - * First, determine if this conversion function applies to the - * conversion path SRC_ID-->DST_ID. If not, return failure; - * otherwise initialize the `priv' field of `cdata' with - * information that remains (almost) constant for this - * conversion path. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_VLEN != src->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype"); - if (H5T_VLEN != dst->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype"); - if (H5T_VLEN_STRING == src->shared->u.vlen.type && H5T_VLEN_STRING == dst->shared->u.vlen.type) { - if ((H5T_CSET_ASCII == src->shared->u.vlen.cset && - H5T_CSET_UTF8 == dst->shared->u.vlen.cset) || - (H5T_CSET_ASCII == dst->shared->u.vlen.cset && H5T_CSET_UTF8 == src->shared->u.vlen.cset)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "The library doesn't convert between strings of ASCII and UTF"); - } /* end if */ - - /* Variable-length types don't need a background buffer */ - cdata->need_bkg = H5T_BKG_NO; - - break; - - case H5T_CONV_FREE: - /* QAK - Nothing to do currently */ - break; - - case H5T_CONV_CONV: - /* - * Conversion. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - - /* Initialize temporary conversion context */ - tmp_conv_ctx = *conv_ctx; - - /* Initialize source & destination strides */ - if (buf_stride) { - assert(buf_stride >= src->shared->size); - assert(buf_stride >= dst->shared->size); - H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); - s_stride = d_stride = (ssize_t)buf_stride; - } /* end if */ - else { - H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); - H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); - s_stride = (ssize_t)src->shared->size; - d_stride = (ssize_t)dst->shared->size; - } /* end else */ - if (bkg) { - if (bkg_stride) - b_stride = (ssize_t)bkg_stride; - else - b_stride = d_stride; - } /* end if */ - else - b_stride = 0; - - /* Get the size of the base types in src & dst */ - src_base_size = H5T_get_size(src->shared->parent); - dst_base_size = H5T_get_size(dst->shared->parent); - - /* Set up conversion path for base elements */ - if (NULL == (tpath = H5T_path_find(src->shared->parent, dst->shared->parent))) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "unable to convert between src and dest datatypes"); - else if (!H5T_path_noop(tpath)) { - if (NULL == (tsrc_cpy = H5T_copy(src->shared->parent, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, - "unable to copy src base type for conversion"); - /* References need to know about the src file */ - if (tsrc_cpy->shared->type == H5T_REFERENCE) - if (H5T_set_loc(tsrc_cpy, src->shared->u.vlen.file, src->shared->u.vlen.loc) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set datatype location"); - - if (NULL == (tdst_cpy = H5T_copy(dst->shared->parent, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, - "unable to copy dst base type for conversion"); - /* References need to know about the dst file */ - if (tdst_cpy->shared->type == H5T_REFERENCE) - if (H5T_set_loc(tdst_cpy, dst->shared->u.vlen.file, dst->shared->u.vlen.loc) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set datatype location"); - - /* Create IDs for the variable-length base datatypes if the conversion path - * uses an application conversion function or if a conversion exception function - * was provided. - */ - if (tpath->conv.is_app || conv_ctx->u.conv.cb_struct.func) { - if ((tsrc_id = H5I_register(H5I_DATATYPE, tsrc_cpy, false)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, - "unable to register ID for source base datatype"); - if ((tdst_id = H5I_register(H5I_DATATYPE, tdst_cpy, false)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, - "unable to register ID for destination base datatype"); - } - - /* Update IDs in conversion context */ - tmp_conv_ctx.u.conv.src_type_id = tsrc_id; - tmp_conv_ctx.u.conv.dst_type_id = tdst_id; - } /* end else-if */ - else - noop_conv = true; - - /* Check if we need a temporary buffer for this conversion */ - if ((parent_is_vlen = H5T_detect_class(dst->shared->parent, H5T_VLEN, false)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_SYSTEM, FAIL, - "internal error when detecting variable-length class"); - if (tpath->cdata.need_bkg || parent_is_vlen) { - /* Set up initial background buffer */ - tmp_buf_size = MAX(src_base_size, dst_base_size); - if (NULL == (tmp_buf = H5FL_BLK_CALLOC(vlen_seq, tmp_buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "memory allocation failed for type conversion"); - } /* end if */ - - /* Get the allocation info */ - if (H5CX_get_vlen_alloc_info(&vl_alloc_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info"); - - /* Set flags to indicate we are writing to or reading from the file */ - if (dst->shared->u.vlen.file != NULL) - write_to_file = true; - - /* Set the flag for nested VL case */ - if (write_to_file && parent_is_vlen && bkg != NULL) - nested = true; - - /* Save info for unraveling on errors */ - orig_d_stride = (size_t)d_stride; - convert_forward = !(d_stride > s_stride); - - /* The outer loop of the type conversion macro, controlling which */ - /* direction the buffer is walked */ - while (nelmts > 0) { - /* Check if we need to go backwards through the buffer */ - if (d_stride > s_stride) { - /* Sanity check */ - assert(s_stride > 0); - assert(d_stride > 0); - assert(b_stride >= 0); - - /* Compute the number of "safe" destination elements at */ - /* the end of the buffer (Those which don't overlap with */ - /* any source elements at the beginning of the buffer) */ - safe = - nelmts - (((nelmts * (size_t)s_stride) + ((size_t)d_stride - 1)) / (size_t)d_stride); - - /* If we're down to the last few elements, just wrap up */ - /* with a "real" reverse copy */ - if (safe < 2) { - s = (uint8_t *)buf + (nelmts - 1) * (size_t)s_stride; - d = (uint8_t *)buf + (nelmts - 1) * (size_t)d_stride; - if (bkg) - b = (uint8_t *)bkg + (nelmts - 1) * (size_t)b_stride; - s_stride = -s_stride; - d_stride = -d_stride; - b_stride = -b_stride; - - safe = nelmts; - } /* end if */ - else { - s = (uint8_t *)buf + (nelmts - safe) * (size_t)s_stride; - d = (uint8_t *)buf + (nelmts - safe) * (size_t)d_stride; - if (bkg) - b = (uint8_t *)bkg + (nelmts - safe) * (size_t)b_stride; - } /* end else */ - } /* end if */ - else { - /* Single forward pass over all data */ - s = d = (uint8_t *)buf; - b = (uint8_t *)bkg; - safe = nelmts; - } /* end else */ - - for (elmtno = 0; elmtno < safe; elmtno++) { - bool is_nil; /* Whether sequence is "nil" */ - - /* Check for "nil" source sequence */ - if ((*(src->shared->u.vlen.cls->isnull))(src->shared->u.vlen.file, s, &is_nil) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't check if VL data is 'nil'"); - else if (is_nil) { - /* Write "nil" sequence to destination location */ - if ((*(dst->shared->u.vlen.cls->setnull))(dst->shared->u.vlen.file, d, b) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't set VL data to 'nil'"); - } /* end else-if */ - else { - size_t seq_len; /* The number of elements in the current sequence */ - - /* Get length of element sequences */ - if ((*(src->shared->u.vlen.cls->getlen))(src->shared->u.vlen.file, s, &seq_len) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "bad sequence length"); - - /* If we are reading from memory and there is no conversion, just get the pointer to - * sequence */ - if (write_to_file && noop_conv) { - /* Get direct pointer to sequence */ - if (NULL == (conv_buf = (*(src->shared->u.vlen.cls->getptr))(s))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid source pointer"); - } /* end if */ - else { - size_t src_size, dst_size; /*source & destination total size in bytes*/ - - src_size = seq_len * src_base_size; - dst_size = seq_len * dst_base_size; - - /* Check if conversion buffer is large enough, resize if - * necessary. If the SEQ_LEN is 0, allocate a minimal size buffer. - */ - if (!seq_len && !conv_buf) { - conv_buf_size = H5T_VLEN_MIN_CONF_BUF_SIZE; - if (NULL == (conv_buf = H5FL_BLK_CALLOC(vlen_seq, conv_buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for type conversion"); - } /* end if */ - else if (conv_buf_size < MAX(src_size, dst_size)) { - /* Only allocate conversion buffer in H5T_VLEN_MIN_CONF_BUF_SIZE increments */ - conv_buf_size = ((MAX(src_size, dst_size) / H5T_VLEN_MIN_CONF_BUF_SIZE) + 1) * - H5T_VLEN_MIN_CONF_BUF_SIZE; - if (NULL == (conv_buf = H5FL_BLK_REALLOC(vlen_seq, conv_buf, conv_buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for type conversion"); - memset(conv_buf, 0, conv_buf_size); - } /* end else-if */ - - /* Read in VL sequence */ - if ((*(src->shared->u.vlen.cls->read))(src->shared->u.vlen.file, s, conv_buf, - src_size) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data"); - } /* end else */ - - if (!noop_conv) { - /* Check if temporary buffer is large enough, resize if necessary */ - /* (Chain off the conversion buffer size) */ - if (tmp_buf && tmp_buf_size < conv_buf_size) { - /* Set up initial background buffer */ - tmp_buf_size = conv_buf_size; - if (NULL == (tmp_buf = H5FL_BLK_REALLOC(vlen_seq, tmp_buf, tmp_buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for type conversion"); - memset(tmp_buf, 0, tmp_buf_size); - } /* end if */ - - /* If we are writing and there is a nested VL type, read - * the sequence into the background buffer */ - if (nested) { - /* Sanity check */ - assert(write_to_file); - - /* Get length of background element sequence */ - if ((*(dst->shared->u.vlen.cls->getlen))(dst->shared->u.vlen.file, b, - &bg_seq_len) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "bad sequence length"); - - /* Read sequence if length > 0 */ - if (bg_seq_len > 0) { - if (tmp_buf_size < (bg_seq_len * MAX(src_base_size, dst_base_size))) { - tmp_buf_size = (bg_seq_len * MAX(src_base_size, dst_base_size)); - if (NULL == - (tmp_buf = H5FL_BLK_REALLOC(vlen_seq, tmp_buf, tmp_buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for type conversion"); - memset(tmp_buf, 0, tmp_buf_size); - } /* end if */ - - /* Read in background VL sequence */ - if ((*(dst->shared->u.vlen.cls->read))(dst->shared->u.vlen.file, b, - tmp_buf, - bg_seq_len * dst_base_size) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data"); - } /* end if */ - - /* If the sequence gets shorter, pad out the original sequence with zeros */ - if (bg_seq_len < seq_len) - memset((uint8_t *)tmp_buf + dst_base_size * bg_seq_len, 0, - (seq_len - bg_seq_len) * dst_base_size); - } /* end if */ - - /* Convert VL sequence */ - tmp_conv_ctx.u.conv.recursive = true; - if (H5T_convert_with_ctx(tpath, tsrc_cpy, tdst_cpy, &tmp_conv_ctx, seq_len, - (size_t)0, (size_t)0, conv_buf, tmp_buf) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "datatype conversion failed"); - tmp_conv_ctx.u.conv.recursive = false; - } /* end if */ - - /* Write sequence to destination location */ - if ((*(dst->shared->u.vlen.cls->write))(dst->shared->u.vlen.file, &vl_alloc_info, d, - conv_buf, b, seq_len, dst_base_size) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data"); - - if (!noop_conv) { - /* For nested VL case, free leftover heap objects from the deeper level if the - * length of new data elements is shorter than the old data elements.*/ - if (nested && seq_len < bg_seq_len) { - uint8_t *tmp; - size_t u; - - /* Sanity check */ - assert(write_to_file); - - tmp = (uint8_t *)tmp_buf + seq_len * dst_base_size; - for (u = seq_len; u < bg_seq_len; u++, tmp += dst_base_size) { - /* Recursively free destination data */ - if (H5T__conv_vlen_nested_free(tmp, dst->shared->parent) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, - "unable to remove heap object"); - } /* end for */ - } /* end if */ - } /* end if */ - } /* end else */ - - /* Indicate that elements have been converted, in case of error */ - conversions_made = true; - - /* Advance pointers */ - s += s_stride; - d += d_stride; - - if (b) - b += b_stride; - } /* end for */ - - /* Decrement number of elements left to convert */ - nelmts -= safe; - } /* end while */ - - break; - - default: /* Some other command we don't know about yet.*/ - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - /* Release converted elements on error */ - if (ret_value < 0 && conversions_made) { - size_t dest_count; - - /* Set up for first pass to destroy references */ - if (nelmts < orig_nelmts || (convert_forward && elmtno < safe)) { - dest_count = orig_nelmts - nelmts; - - /* Set pointer to correct location, based on direction chosen */ - if (convert_forward) { - d = (uint8_t *)buf; - dest_count += elmtno; /* Include partial iteration in first pass, for forward conversions */ - } - else - d = (uint8_t *)buf + (nelmts * orig_d_stride); - - /* Destroy vlen elements that have already been converted */ - while (dest_count > 0) { - H5T_vlen_reclaim_elmt(d, dst); /* Ignore errors at this point */ - d += orig_d_stride; - dest_count--; - } - } - - /* Do any remaining partial iteration, if converting backwards */ - if (!convert_forward && elmtno < safe) { - dest_count = elmtno; - - /* Set pointer to correct location */ - if (d_stride > 0) - d = (uint8_t *)buf + ((nelmts - safe) * orig_d_stride); - else - d = (uint8_t *)buf + ((nelmts - elmtno) * orig_d_stride); - - /* Destroy references that have already been converted */ - while (dest_count > 0) { - H5T_vlen_reclaim_elmt(d, dst); /* Ignore errors at this point */ - d += orig_d_stride; - dest_count--; - } - } - } - - if (tsrc_id >= 0) { - if (H5I_dec_ref(tsrc_id) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); - } - else if (tsrc_cpy) { - if (H5T_close(tsrc_cpy) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); - } - if (tdst_id >= 0) { - if (H5I_dec_ref(tdst_id) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); - } - else if (tdst_cpy) { - if (H5T_close(tdst_cpy) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); - } - - /* If the conversion buffer doesn't need to be freed, reset its pointer */ - if (write_to_file && noop_conv) - conv_buf = NULL; - /* Release the conversion buffer (always allocated, except on errors) */ - if (conv_buf) - conv_buf = H5FL_BLK_FREE(vlen_seq, conv_buf); - /* Release the background buffer, if we have one */ - if (tmp_buf) - tmp_buf = H5FL_BLK_FREE(vlen_seq, tmp_buf); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_vlen() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_array - * - * Purpose: Converts between array datatypes in memory and on disk. - * This is a soft conversion function. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_array(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *_bkg) -{ - H5T_conv_array_t *priv = NULL; /* Private conversion data */ - H5T_conv_ctx_t tmp_conv_ctx = {0}; /* Temporary conversion context */ - H5T_t *tsrc_cpy = NULL; /* Temporary copy of source base datatype */ - H5T_t *tdst_cpy = NULL; /* Temporary copy of destination base datatype */ - hid_t tsrc_id = H5I_INVALID_HID; /* Temporary type atom */ - hid_t tdst_id = H5I_INVALID_HID; /* Temporary type atom */ - uint8_t *sp, *dp, *bp; /* Source, dest, and bkg traversal ptrs */ - ssize_t src_delta, dst_delta, bkg_delta; /* Source, dest, and bkg strides */ - int direction; /* Direction of traversal */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - /* - * First, determine if this conversion function applies to the - * conversion path SRC-->DST. If not, return failure; - * otherwise initialize the `priv' field of `cdata' with - * information that remains (almost) constant for this - * conversion path. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - assert(H5T_ARRAY == src->shared->type); - assert(H5T_ARRAY == dst->shared->type); - - /* Check the number and sizes of the dimensions */ - if (src->shared->u.array.ndims != dst->shared->u.array.ndims) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "array datatypes do not have the same number of dimensions"); - for (unsigned u = 0; u < src->shared->u.array.ndims; u++) - if (src->shared->u.array.dim[u] != dst->shared->u.array.dim[u]) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "array datatypes do not have the same sizes of dimensions"); - - /* Initialize parent type conversion if necessary. We need to do this here because we need to - * report whether we need a background buffer or not. */ - if (!cdata->priv) { - /* Allocate private data */ - if (NULL == (priv = (H5T_conv_array_t *)(cdata->priv = calloc(1, sizeof(*priv))))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - - /* Find conversion path between parent types */ - if (NULL == (priv->tpath = H5T_path_find(src->shared->parent, dst->shared->parent))) { - free(priv); - cdata->priv = NULL; - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "unable to convert between src and dest datatype"); - } - - /* Array datatypes don't need a background buffer by themselves, but the parent type might. - * Pass the need_bkg field through to the upper layer. */ - cdata->need_bkg = priv->tpath->cdata.need_bkg; - } - - break; - - case H5T_CONV_FREE: - /* - * Free private data - */ - free(cdata->priv); - cdata->priv = NULL; - - break; - - case H5T_CONV_CONV: - /* - * Conversion. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - priv = (H5T_conv_array_t *)cdata->priv; - - /* Initialize temporary conversion context */ - tmp_conv_ctx = *conv_ctx; - - /* - * Do we process the values from beginning to end or vice - * versa? Also, how many of the elements have the source and - * destination areas overlapping? - */ - if (src->shared->size >= dst->shared->size || buf_stride > 0) { - sp = dp = (uint8_t *)_buf; - bp = _bkg; - direction = 1; - } - else { - sp = (uint8_t *)_buf + (nelmts - 1) * (buf_stride ? buf_stride : src->shared->size); - dp = (uint8_t *)_buf + (nelmts - 1) * (buf_stride ? buf_stride : dst->shared->size); - bp = _bkg ? (uint8_t *)_bkg + (nelmts - 1) * (bkg_stride ? bkg_stride : dst->shared->size) - : NULL; - direction = -1; - } - - /* - * Direction & size of buffer traversal. - */ - H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); - H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); - H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); - src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src->shared->size); - dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst->shared->size); - bkg_delta = (ssize_t)direction * (ssize_t)(bkg_stride ? bkg_stride : dst->shared->size); - - /* Set up conversion path for base elements */ - if (!H5T_path_noop(priv->tpath)) { - if (NULL == (tsrc_cpy = H5T_copy(src->shared->parent, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, - "unable to copy src base type for conversion"); - - if (NULL == (tdst_cpy = H5T_copy(dst->shared->parent, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, - "unable to copy dst base type for conversion"); - - /* Create IDs for the array base datatypes if the conversion path uses an - * application conversion function or if a conversion exception function - * was provided. - */ - if (priv->tpath->conv.is_app || conv_ctx->u.conv.cb_struct.func) { - if ((tsrc_id = H5I_register(H5I_DATATYPE, tsrc_cpy, false)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, - "unable to register ID for source base datatype"); - if ((tdst_id = H5I_register(H5I_DATATYPE, tdst_cpy, false)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, - "unable to register ID for destination base datatype"); - } - - /* Update IDs in conversion context */ - tmp_conv_ctx.u.conv.src_type_id = tsrc_id; - tmp_conv_ctx.u.conv.dst_type_id = tdst_id; - } - - /* Perform the actual conversion */ - tmp_conv_ctx.u.conv.recursive = true; - for (size_t elmtno = 0; elmtno < nelmts; elmtno++) { - /* Copy the source array into the correct location for the destination */ - memmove(dp, sp, src->shared->size); - - /* Convert array */ - if (H5T_convert_with_ctx(priv->tpath, tsrc_cpy, tdst_cpy, &tmp_conv_ctx, - src->shared->u.array.nelem, (size_t)0, (size_t)0, dp, bp) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "datatype conversion failed"); - - /* Advance the source, destination, and background pointers */ - sp += src_delta; - dp += dst_delta; - if (bp) - bp += bkg_delta; - } /* end for */ - tmp_conv_ctx.u.conv.recursive = false; - - break; - - default: /* Some other command we don't know about yet.*/ - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - if (tsrc_id >= 0) { - if (H5I_dec_ref(tsrc_id) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); - } - else if (tsrc_cpy) { - if (H5T_close(tsrc_cpy) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); - } - if (tdst_id >= 0) { - if (H5I_dec_ref(tdst_id) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); - } - else if (tdst_cpy) { - if (H5T_close(tdst_cpy) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); - } - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_array() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ref - * - * Purpose: Converts between reference datatypes in memory and on disk. - * This is a soft conversion function. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ref(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg) -{ - uint8_t *s = NULL; /* source buffer */ - uint8_t *d = NULL; /* destination buffer */ - uint8_t *b = NULL; /* background buffer */ - ssize_t s_stride = 0; /* src stride */ - ssize_t d_stride = 0; /* dst stride */ - ssize_t b_stride; /* bkg stride */ - size_t safe = 0; /* how many elements are safe to process in each pass */ - void *conv_buf = NULL; /* temporary conversion buffer */ - size_t conv_buf_size = 0; /* size of conversion buffer in bytes */ - size_t elmtno = 0; /* element number counter */ - size_t orig_d_stride = 0; /* Original destination stride (used for error handling) */ - size_t orig_nelmts = nelmts; /* Original # of elements to convert (used for error handling) */ - bool convert_forward = - true; /* Current direction of conversion (forward or backward, used for error handling) */ - bool conversions_made = - false; /* Flag to indicate conversions have been performed, used for error handling */ - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - /* - * First, determine if this conversion function applies to the - * conversion path SRC-->DST. If not, return failure; - * otherwise initialize the `priv' field of `cdata' with - * information that remains (almost) constant for this - * conversion path. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_REFERENCE != src->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype"); - if (H5T_REFERENCE != dst->shared->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype"); - /* Only allow for source reference that is not an opaque type, destination must be opaque */ - if (!dst->shared->u.atomic.u.r.opaque) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not an H5T_STD_REF datatype"); - - /* Reference types don't need a background buffer */ - cdata->need_bkg = H5T_BKG_NO; - break; - - case H5T_CONV_FREE: - break; - - case H5T_CONV_CONV: { - /* - * Conversion. - */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - - assert(src->shared->u.atomic.u.r.cls); - - /* Initialize source & destination strides */ - if (buf_stride) { - assert(buf_stride >= src->shared->size); - assert(buf_stride >= dst->shared->size); - H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); - s_stride = d_stride = (ssize_t)buf_stride; - } /* end if */ - else { - H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); - H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); - s_stride = (ssize_t)src->shared->size; - d_stride = (ssize_t)dst->shared->size; - } /* end else */ - if (bkg) { - if (bkg_stride) - b_stride = (ssize_t)bkg_stride; - else - b_stride = d_stride; - } /* end if */ - else - b_stride = 0; - - /* Save info for unraveling on errors */ - orig_d_stride = (size_t)d_stride; - convert_forward = !(d_stride > s_stride); - - /* The outer loop of the type conversion macro, controlling which */ - /* direction the buffer is walked */ - while (nelmts > 0) { - /* Check if we need to go backwards through the buffer */ - if (d_stride > s_stride) { - /* Sanity check */ - assert(s_stride > 0); - assert(d_stride > 0); - assert(b_stride >= 0); - - /* Compute the number of "safe" destination elements at */ - /* the end of the buffer (Those which don't overlap with */ - /* any source elements at the beginning of the buffer) */ - safe = - nelmts - (((nelmts * (size_t)s_stride) + ((size_t)d_stride - 1)) / (size_t)d_stride); - - /* If we're down to the last few elements, just wrap up */ - /* with a "real" reverse copy */ - if (safe < 2) { - s = (uint8_t *)buf + (nelmts - 1) * (size_t)s_stride; - d = (uint8_t *)buf + (nelmts - 1) * (size_t)d_stride; - if (bkg) - b = (uint8_t *)bkg + (nelmts - 1) * (size_t)b_stride; - s_stride = -s_stride; - d_stride = -d_stride; - b_stride = -b_stride; - - safe = nelmts; - } /* end if */ - else { - s = (uint8_t *)buf + (nelmts - safe) * (size_t)s_stride; - d = (uint8_t *)buf + (nelmts - safe) * (size_t)d_stride; - if (bkg) - b = (uint8_t *)bkg + (nelmts - safe) * (size_t)b_stride; - } /* end else */ - } /* end if */ - else { - /* Single forward pass over all data */ - s = d = (uint8_t *)buf; - b = (uint8_t *)bkg; - safe = nelmts; - } /* end else */ - - for (elmtno = 0; elmtno < safe; elmtno++) { - size_t buf_size; - bool dst_copy = false; - bool is_nil; /* Whether reference is "nil" */ - - /* Check for "nil" source reference */ - if ((*(src->shared->u.atomic.u.r.cls->isnull))(src->shared->u.atomic.u.r.file, s, - &is_nil) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, - "can't check if reference data is 'nil'"); - - if (is_nil) { - /* Write "nil" reference to destination location */ - if ((*(dst->shared->u.atomic.u.r.cls->setnull))(dst->shared->u.atomic.u.r.file, d, - b) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, - "can't set reference data to 'nil'"); - } /* end else-if */ - else { - /* Get size of references */ - if (0 == (buf_size = src->shared->u.atomic.u.r.cls->getsize( - src->shared->u.atomic.u.r.file, s, src->shared->size, - dst->shared->u.atomic.u.r.file, &dst_copy))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to obtain size of reference"); - - /* Check if conversion buffer is large enough, resize if necessary. */ - if (conv_buf_size < buf_size) { - conv_buf_size = buf_size; - if (NULL == (conv_buf = H5FL_BLK_REALLOC(ref_seq, conv_buf, conv_buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for type conversion"); - memset(conv_buf, 0, conv_buf_size); - } /* end if */ - - if (dst_copy && (src->shared->u.atomic.u.r.loc == H5T_LOC_DISK)) - H5MM_memcpy(conv_buf, s, buf_size); - else { - /* Read reference */ - if (src->shared->u.atomic.u.r.cls->read( - src->shared->u.atomic.u.r.file, s, src->shared->size, - dst->shared->u.atomic.u.r.file, conv_buf, buf_size) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read reference data"); - } /* end else */ - - if (dst_copy && (dst->shared->u.atomic.u.r.loc == H5T_LOC_DISK)) - H5MM_memcpy(d, conv_buf, buf_size); - else { - /* Write reference to destination location */ - if (dst->shared->u.atomic.u.r.cls->write( - src->shared->u.atomic.u.r.file, conv_buf, buf_size, - src->shared->u.atomic.u.r.rtype, dst->shared->u.atomic.u.r.file, d, - dst->shared->size, b) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write reference data"); - } /* end else */ - } /* end else */ - - /* Indicate that elements have been converted, in case of error */ - conversions_made = true; - - /* Advance pointers */ - s += s_stride; - d += d_stride; - - if (b) - b += b_stride; - } /* end for */ - - /* Decrement number of elements left to convert */ - nelmts -= safe; - } /* end while */ - } /* end case */ - break; - - default: /* Some other command we don't know about yet.*/ - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - /* Release converted elements on error */ - if (ret_value < 0 && conversions_made) { - H5R_ref_priv_t ref_priv; - size_t dest_count; - - /* Set up for first pass to destroy references */ - if (nelmts < orig_nelmts || (convert_forward && elmtno < safe)) { - dest_count = orig_nelmts - nelmts; - - /* Set pointer to correct location, based on direction chosen */ - if (convert_forward) { - d = (uint8_t *)buf; - dest_count += elmtno; /* Include partial iteration in first pass, for forward conversions */ - } - else - d = (uint8_t *)buf + (nelmts * orig_d_stride); - - /* Destroy references that have already been converted */ - while (dest_count > 0) { - memcpy(&ref_priv, d, sizeof(H5R_ref_priv_t)); - H5R__destroy(&ref_priv); /* Ignore errors at this point */ - d += orig_d_stride; - dest_count--; - } - } - - /* Do any remaining partial iteration, if converting backwards */ - if (!convert_forward && elmtno < safe) { - dest_count = elmtno; - - /* Set pointer to correct location */ - if (d_stride > 0) - d = (uint8_t *)buf + ((nelmts - safe) * orig_d_stride); - else - d = (uint8_t *)buf + ((nelmts - elmtno) * orig_d_stride); - - /* Destroy references that have already been converted */ - while (dest_count > 0) { - memcpy(&ref_priv, d, sizeof(H5R_ref_priv_t)); - H5R__destroy(&ref_priv); /* Ignore errors at this point */ - d += orig_d_stride; - dest_count--; - } - } - } - - /* Release the conversion buffer (always allocated, except on errors) */ - if (conv_buf) - conv_buf = H5FL_BLK_FREE(ref_seq, conv_buf); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_ref() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_i_i - * - * Purpose: Convert one integer type to another. This is the catch-all - * function for integer conversions and is probably not - * particularly fast. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_i_i(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - ssize_t src_delta, dst_delta; /*source & destination stride */ - int direction; /*direction of traversal */ - size_t elmtno; /*element number */ - size_t half_size; /*half the type size */ - size_t olap; /*num overlapping elements */ - uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t *src_rev = NULL; /*order-reversed source buffer */ - uint8_t dbuf[64] = {0}; /*temp destination buffer */ - size_t first; - ssize_t sfirst; /*a signed version of `first' */ - size_t i; /*Local index variables */ - H5T_conv_ret_t except_ret; /*return of callback function */ - bool reverse; /*if reverse the order of destination */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (H5T_ORDER_LE != dst->shared->u.atomic.order && H5T_ORDER_BE != dst->shared->u.atomic.order) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst->shared->size > sizeof dbuf) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - cdata->need_bkg = H5T_BKG_NO; - break; - - case H5T_CONV_FREE: - break; - - case H5T_CONV_CONV: - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - - /* - * Do we process the values from beginning to end or vice versa? Also, - * how many of the elements have the source and destination areas - * overlapping? - */ - if (src->shared->size == dst->shared->size || buf_stride) { - sp = dp = (uint8_t *)buf; - direction = 1; - olap = nelmts; - } - else if (src->shared->size >= dst->shared->size) { - double olap_d = - ceil((double)(dst->shared->size) / (double)(src->shared->size - dst->shared->size)); - - olap = (size_t)olap_d; - sp = dp = (uint8_t *)buf; - direction = 1; - } - else { - double olap_d = - ceil((double)(src->shared->size) / (double)(dst->shared->size - src->shared->size)); - olap = (size_t)olap_d; - sp = (uint8_t *)buf + (nelmts - 1) * src->shared->size; - dp = (uint8_t *)buf + (nelmts - 1) * dst->shared->size; - direction = -1; - } - - /* - * Direction & size of buffer traversal. - */ - H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); - H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); - H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); - src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src->shared->size); - dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst->shared->size); - - /* Allocate space for order-reversed source buffer */ - src_rev = (uint8_t *)H5MM_calloc(src->shared->size); - - /* The conversion loop */ - for (elmtno = 0; elmtno < nelmts; elmtno++) { - - /* - * If the source and destination buffers overlap then use a - * temporary buffer for the destination. - */ - if (direction > 0) { - s = sp; - d = elmtno < olap ? dbuf : dp; - } - else { - s = sp; - d = elmtno + olap >= nelmts ? dbuf : dp; - } -#ifndef NDEBUG - /* I don't quite trust the overlap calculations yet */ - if (d == dbuf) { - assert((dp >= sp && dp < sp + src->shared->size) || - (sp >= dp && sp < dp + dst->shared->size)); - } - else { - assert((dp < sp && dp + dst->shared->size <= sp) || - (sp < dp && sp + src->shared->size <= dp)); - } -#endif - - /* - * Put the data in little endian order so our loops aren't so - * complicated. We'll do all the conversion stuff assuming - * little endian and then we'll fix the order at the end. - */ - if (H5T_ORDER_BE == src->shared->u.atomic.order) { - half_size = src->shared->size / 2; - for (i = 0; i < half_size; i++) { - uint8_t tmp = s[src->shared->size - (i + 1)]; - s[src->shared->size - (i + 1)] = s[i]; - s[i] = tmp; - } - } - - /* - * What is the bit number for the msb bit of S which is set? The - * bit number is relative to the significant part of the number. - */ - sfirst = H5T__bit_find(s, src->shared->u.atomic.offset, src->shared->u.atomic.prec, - H5T_BIT_MSB, true); - first = (size_t)sfirst; - - /* Set these variables to default */ - except_ret = H5T_CONV_UNHANDLED; - reverse = true; - - if (sfirst < 0) { - /* - * The source has no bits set and must therefore be zero. - * Set the destination to zero. - */ - H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, false); - } - else if (H5T_SGN_NONE == src->shared->u.atomic.u.i.sign && - H5T_SGN_NONE == dst->shared->u.atomic.u.i.sign) { - /* - * Source and destination are both unsigned, but if the - * source has more precision bits than the destination then - * it's possible to overflow. When overflow occurs the - * destination will be set to the maximum possible value. - */ - if (src->shared->u.atomic.prec <= dst->shared->u.atomic.prec) { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - src->shared->u.atomic.prec); - H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, - dst->shared->u.atomic.prec - src->shared->u.atomic.prec, false); - } - else if (first >= dst->shared->u.atomic.prec) { - /*overflow*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - H5T__reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, true); - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) - /*Don't reverse because user handles it already*/ - reverse = false; - } - else { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - dst->shared->u.atomic.prec); - } - } - else if (H5T_SGN_2 == src->shared->u.atomic.u.i.sign && - H5T_SGN_NONE == dst->shared->u.atomic.u.i.sign) { - /* - * If the source is signed and the destination isn't then we - * can have overflow if the source contains more bits than - * the destination (destination is set to the maximum - * possible value) or overflow if the source is negative - * (destination is set to zero). - */ - if (first + 1 == src->shared->u.atomic.prec) { - /*overflow - source is negative*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - H5T__reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, false); - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) - /*Don't reverse because user handles it already*/ - reverse = false; - } - else if (src->shared->u.atomic.prec < dst->shared->u.atomic.prec) { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - src->shared->u.atomic.prec - 1); - H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec - 1, - (dst->shared->u.atomic.prec - src->shared->u.atomic.prec) + 1, false); - } - else if (first >= dst->shared->u.atomic.prec) { - /*overflow - source is positive*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - H5T__reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) - H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, true); - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) - /*Don't reverse because user handles it already*/ - reverse = false; - } - else { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - dst->shared->u.atomic.prec); - } - } - else if (H5T_SGN_NONE == src->shared->u.atomic.u.i.sign && - H5T_SGN_2 == dst->shared->u.atomic.u.i.sign) { - /* - * If the source is not signed but the destination is then - * overflow can occur in which case the destination is set to - * the largest possible value (all bits set except the msb). - */ - if (first + 1 >= dst->shared->u.atomic.prec) { - /*overflow*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - H5T__reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec - 1, - true); - H5T__bit_set(d, (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec - 1), - (size_t)1, false); - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) - /*Don't reverse because user handles it already*/ - reverse = false; - } - else if (src->shared->u.atomic.prec < dst->shared->u.atomic.prec) { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - src->shared->u.atomic.prec); - H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, - dst->shared->u.atomic.prec - src->shared->u.atomic.prec, false); - } - else { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - dst->shared->u.atomic.prec); - } - } - else if (first + 1 == src->shared->u.atomic.prec) { - /* - * Both the source and the destination are signed and the - * source value is negative. We could experience overflow - * if the destination isn't wide enough in which case the - * destination is set to a negative number with the largest - * possible magnitude. - */ - ssize_t sfz = H5T__bit_find(s, src->shared->u.atomic.offset, - src->shared->u.atomic.prec - 1, H5T_BIT_MSB, false); - size_t fz = (size_t)sfz; - - if (sfz >= 0 && fz + 1 >= dst->shared->u.atomic.prec) { - /*overflow*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - H5T__reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec - 1, - false); - H5T__bit_set(d, (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec - 1), - (size_t)1, true); - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) - /*Don't reverse because user handles it already*/ - reverse = false; - } - else if (src->shared->u.atomic.prec < dst->shared->u.atomic.prec) { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - src->shared->u.atomic.prec); - H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, - dst->shared->u.atomic.prec - src->shared->u.atomic.prec, true); - } - else { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - dst->shared->u.atomic.prec); - } - } - else { - /* - * Source and destination are both signed but the source - * value is positive. We could have an overflow in which - * case the destination is set to the largest possible - * positive value. - */ - if (first + 1 >= dst->shared->u.atomic.prec) { - /*overflow*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - H5T__reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec - 1, - true); - H5T__bit_set(d, (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec - 1), - (size_t)1, false); - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) - /*Don't reverse because user handles it already*/ - reverse = false; - } - else if (src->shared->u.atomic.prec < dst->shared->u.atomic.prec) { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - src->shared->u.atomic.prec); - H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, - dst->shared->u.atomic.prec - src->shared->u.atomic.prec, false); - } - else { - H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, - dst->shared->u.atomic.prec); - } - } - - /* - * Set padding areas in destination. - */ - if (dst->shared->u.atomic.offset > 0) { - assert(H5T_PAD_ZERO == dst->shared->u.atomic.lsb_pad || - H5T_PAD_ONE == dst->shared->u.atomic.lsb_pad); - H5T__bit_set(d, (size_t)0, dst->shared->u.atomic.offset, - (bool)(H5T_PAD_ONE == dst->shared->u.atomic.lsb_pad)); - } - if (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec != 8 * dst->shared->size) { - assert(H5T_PAD_ZERO == dst->shared->u.atomic.msb_pad || - H5T_PAD_ONE == dst->shared->u.atomic.msb_pad); - H5T__bit_set(d, dst->shared->u.atomic.offset + dst->shared->u.atomic.prec, - 8 * dst->shared->size - - (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec), - (bool)(H5T_PAD_ONE == dst->shared->u.atomic.msb_pad)); - } - - /* - * Put the destination in the correct byte order. See note at - * beginning of loop. - */ - if (H5T_ORDER_BE == dst->shared->u.atomic.order && reverse) { - half_size = dst->shared->size / 2; - for (i = 0; i < half_size; i++) { - uint8_t tmp = d[dst->shared->size - (i + 1)]; - d[dst->shared->size - (i + 1)] = d[i]; - d[i] = tmp; - } - } - - /* - * If we had used a temporary buffer for the destination then we - * should copy the value to the true destination buffer. - */ - if (d == dbuf) - H5MM_memcpy(dp, d, dst->shared->size); - - /* Advance source & destination pointers by delta amounts */ - sp += src_delta; - dp += dst_delta; - } /* end for */ - - break; - - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - if (src_rev) - H5MM_free(src_rev); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_i_i() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_f_f - * - * Purpose: Convert one floating point type to another. This is a catch - * all for floating point conversions and is probably not - * particularly fast! - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_f_f(const H5T_t *src_p, const H5T_t *dst_p, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - /* Traversal-related variables */ - H5T_atomic_t src; /*atomic source info */ - H5T_atomic_t dst; /*atomic destination info */ - ssize_t src_delta, dst_delta; /*source & destination stride */ - int direction; /*forward or backward traversal */ - size_t elmtno; /*element number */ - size_t half_size; /*half the type size */ - size_t tsize; /*type size for swapping bytes */ - size_t olap; /*num overlapping elements */ - ssize_t bitno = 0; /*bit number */ - uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t *src_rev = NULL; /*order-reversed source buffer */ - uint8_t dbuf[64] = {0}; /*temp destination buffer */ - uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ - - /* Conversion-related variables */ - int64_t expo; /*exponent */ - hssize_t expo_max; /*maximum possible dst exponent */ - size_t msize = 0; /*useful size of mantissa in src*/ - size_t mpos; /*offset to useful mant is src */ - uint64_t sign; /*source sign bit value */ - size_t mrsh; /*amount to right shift mantissa*/ - bool carry = false; /*carry after rounding mantissa */ - size_t i; /*miscellaneous counters */ - size_t implied; /*destination implied bits */ - bool denormalized = false; /*is either source or destination denormalized?*/ - H5T_conv_ret_t except_ret; /*return of callback function */ - bool reverse; /*if reverse the order of destination */ - herr_t ret_value = SUCCEED; /*return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - if (NULL == src_p || NULL == dst_p) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - src = src_p->shared->u.atomic; - dst = dst_p->shared->u.atomic; - if (H5T_ORDER_LE != src.order && H5T_ORDER_BE != src.order && H5T_ORDER_VAX != src.order) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (H5T_ORDER_LE != dst.order && H5T_ORDER_BE != dst.order && H5T_ORDER_VAX != dst.order) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst_p->shared->size > sizeof(dbuf)) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - if (8 * sizeof(expo) - 1 < src.u.f.esize || 8 * sizeof(expo) - 1 < dst.u.f.esize) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); - cdata->need_bkg = H5T_BKG_NO; - break; - - case H5T_CONV_FREE: - break; - - case H5T_CONV_CONV: - if (NULL == src_p || NULL == dst_p) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - - src = src_p->shared->u.atomic; - dst = dst_p->shared->u.atomic; - expo_max = ((hssize_t)1 << dst.u.f.esize) - 1; - - /* - * Do we process the values from beginning to end or vice versa? Also, - * how many of the elements have the source and destination areas - * overlapping? - */ - if (src_p->shared->size == dst_p->shared->size || buf_stride) { - sp = dp = (uint8_t *)buf; - direction = 1; - olap = nelmts; - } - else if (src_p->shared->size >= dst_p->shared->size) { - double olap_d = - ceil((double)(dst_p->shared->size) / (double)(src_p->shared->size - dst_p->shared->size)); - olap = (size_t)olap_d; - sp = dp = (uint8_t *)buf; - direction = 1; - } - else { - double olap_d = - ceil((double)(src_p->shared->size) / (double)(dst_p->shared->size - src_p->shared->size)); - olap = (size_t)olap_d; - sp = (uint8_t *)buf + (nelmts - 1) * src_p->shared->size; - dp = (uint8_t *)buf + (nelmts - 1) * dst_p->shared->size; - direction = -1; - } - - /* - * Direction & size of buffer traversal. - */ - H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); - H5_CHECK_OVERFLOW(src_p->shared->size, size_t, ssize_t); - H5_CHECK_OVERFLOW(dst_p->shared->size, size_t, ssize_t); - src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src_p->shared->size); - dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst_p->shared->size); - - /* Allocate space for order-reversed source buffer */ - src_rev = (uint8_t *)H5MM_calloc(src_p->shared->size); - - /* The conversion loop */ - for (elmtno = 0; elmtno < nelmts; elmtno++) { - /* Set these variables to default */ - except_ret = H5T_CONV_UNHANDLED; - reverse = true; - - /* - * If the source and destination buffers overlap then use a - * temporary buffer for the destination. - */ - if (direction > 0) { - s = sp; - d = elmtno < olap ? dbuf : dp; - } - else { - s = sp; - d = elmtno + olap >= nelmts ? dbuf : dp; - } -#ifndef NDEBUG - /* I don't quite trust the overlap calculations yet */ - if (d == dbuf) { - assert((dp >= sp && dp < sp + src_p->shared->size) || - (sp >= dp && sp < dp + dst_p->shared->size)); - } - else { - assert((dp < sp && dp + dst_p->shared->size <= sp) || - (sp < dp && sp + src_p->shared->size <= dp)); - } -#endif - - /* - * Put the data in little endian order so our loops aren't so - * complicated. We'll do all the conversion stuff assuming - * little endian and then we'll fix the order at the end. - */ - if (H5T_ORDER_BE == src.order) { - half_size = src_p->shared->size / 2; - for (i = 0; i < half_size; i++) { - tmp1 = s[src_p->shared->size - (i + 1)]; - s[src_p->shared->size - (i + 1)] = s[i]; - s[i] = tmp1; - } - } - else if (H5T_ORDER_VAX == src.order) { - tsize = src_p->shared->size; - assert(0 == tsize % 2); - - for (i = 0; i < tsize; i += 4) { - tmp1 = s[i]; - tmp2 = s[i + 1]; - - s[i] = s[(tsize - 2) - i]; - s[i + 1] = s[(tsize - 1) - i]; - - s[(tsize - 2) - i] = tmp1; - s[(tsize - 1) - i] = tmp2; - } - } - - /* - * Find the sign bit value of the source. - */ - sign = H5T__bit_get_d(s, src.u.f.sign, (size_t)1); - - /* - * Check for special cases: +0, -0, +Inf, -Inf, NaN - */ - if (H5T__bit_find(s, src.u.f.mpos, src.u.f.msize, H5T_BIT_LSB, true) < 0) { - if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, true) < 0) { - /* +0 or -0 */ - H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); - H5T__bit_set(d, dst.u.f.epos, dst.u.f.esize, false); - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); - goto padding; - } - else if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { - /* +Inf or -Inf */ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - if (sign) - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_NINF, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - else - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_PINF, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); - H5T__bit_set(d, dst.u.f.epos, dst.u.f.esize, true); - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); - /*If the destination no implied mantissa bit, we'll need to set - *the 1st bit of mantissa to 1. The Intel-Linux long double is - *this case.*/ - if (H5T_NORM_NONE == dst.u.f.norm) - H5T__bit_set(d, dst.u.f.mpos + dst.u.f.msize - 1, (size_t)1, true); - } - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - - goto padding; - } - } - else if (H5T_NORM_NONE == src.u.f.norm && - H5T__bit_find(s, src.u.f.mpos, src.u.f.msize - 1, H5T_BIT_LSB, true) < 0 && - H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { - /*This is a special case for the source of no implied mantissa bit. - *If the exponent bits are all 1s and only the 1st bit of mantissa - *is set to 1. It's infinity. The Intel-Linux "long double" is this case.*/ - /* +Inf or -Inf */ - if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); - if (sign) - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_NINF, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - else - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_PINF, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); - H5T__bit_set(d, dst.u.f.epos, dst.u.f.esize, true); - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); - /*If the destination no implied mantissa bit, we'll need to set - *the 1st bit of mantissa to 1. The Intel-Linux long double is - *this case.*/ - if (H5T_NORM_NONE == dst.u.f.norm) - H5T__bit_set(d, dst.u.f.mpos + dst.u.f.msize - 1, (size_t)1, true); - } - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); - - goto padding; - /* Temporary solution to handle VAX special values. - * Note that even though we don't support VAX anymore, we - * still need to handle legacy VAX files so this code must - * remain in place. - */ - } - else if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { - /* NaN */ - if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_NAN, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, - src_rev, d, conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - /* There are many NaN values, so we just set all bits of - * the significand. */ - H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); - H5T__bit_set(d, dst.u.f.epos, dst.u.f.esize, true); - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, true); - } - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); - - goto padding; - } - - /* - * Get the exponent as an unsigned quantity from the section of - * the source bit field where it's located. Don't worry about - * the exponent bias yet. - */ - expo = (int64_t)H5T__bit_get_d(s, src.u.f.epos, src.u.f.esize); - - if (expo == 0) - denormalized = true; - - /* - * Set markers for the source mantissa, excluding the leading `1' - * (might be implied). - */ - implied = 1; - mpos = src.u.f.mpos; - mrsh = 0; - if (0 == expo || H5T_NORM_NONE == src.u.f.norm) { - if ((bitno = H5T__bit_find(s, src.u.f.mpos, src.u.f.msize, H5T_BIT_MSB, true)) > 0) { - msize = (size_t)bitno; - } - else if (0 == bitno) { - msize = 1; - H5T__bit_set(s, src.u.f.mpos, (size_t)1, false); - } - } - else if (H5T_NORM_IMPLIED == src.u.f.norm) { - msize = src.u.f.msize; - } - else { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "normalization method not implemented yet"); - } - - /* - * The sign for the destination is the same as the sign for the - * source in all cases. - */ - H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); - - /* - * Calculate the true source exponent by adjusting according to - * the source exponent bias. - */ - if (0 == expo || H5T_NORM_NONE == src.u.f.norm) { - assert(bitno >= 0); - expo -= (int64_t)((src.u.f.ebias - 1) + (src.u.f.msize - (size_t)bitno)); - } - else if (H5T_NORM_IMPLIED == src.u.f.norm) { - expo -= (int64_t)src.u.f.ebias; - } - else { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "normalization method not implemented yet"); - } - - /* - * If the destination is not normalized then right shift the - * mantissa by one. - */ - if (H5T_NORM_NONE == dst.u.f.norm) - mrsh++; - - /* - * Calculate the destination exponent by adding the destination - * bias and clipping by the minimum and maximum possible - * destination exponent values. - */ - expo += (int64_t)dst.u.f.ebias; - - if (expo < -(hssize_t)(dst.u.f.msize)) { - /* The exponent is way too small. Result is zero. */ - expo = 0; - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); - msize = 0; - } - else if (expo <= 0) { - /* - * The exponent is too small to fit in the exponent field, - * but by shifting the mantissa to the right we can - * accommodate that value. The mantissa of course is no - * longer normalized. - */ - mrsh += (size_t)(1 - expo); - expo = 0; - denormalized = true; - } - else if (expo >= expo_max) { - /* - * The exponent is too large to fit in the available region - * or it results in the maximum possible value. Use positive - * or negative infinity instead unless the application - * specifies something else. Before calling the overflow - * handler make sure the source buffer we hand it is in the - * original byte order. - */ - if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - expo = expo_max; - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); - msize = 0; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) { - reverse = false; - goto next; - } - } - - /* - * If the destination mantissa is smaller than the source - * mantissa then round the source mantissa. Rounding may cause a - * carry in which case the exponent has to be re-evaluated for - * overflow. That is, if `carry' is clear then the implied - * mantissa bit is `1', else it is `10' binary. - */ - if (msize > 0 && mrsh <= dst.u.f.msize && mrsh + msize > dst.u.f.msize) { - bitno = (ssize_t)(mrsh + msize - dst.u.f.msize); - assert(bitno >= 0 && (size_t)bitno <= msize); - /* If the 1st bit being cut off is set and source isn't denormalized.*/ - if (H5T__bit_get_d(s, (mpos + (size_t)bitno) - 1, (size_t)1) && !denormalized) { - /* Don't do rounding if exponent is 111...110 and mantissa is 111...11. - * To do rounding and increment exponent in this case will create an infinity value.*/ - if ((H5T__bit_find(s, mpos + (size_t)bitno, msize - (size_t)bitno, H5T_BIT_LSB, - false) >= 0 || - expo < expo_max - 1)) { - carry = H5T__bit_inc(s, mpos + (size_t)bitno - 1, 1 + msize - (size_t)bitno); - if (carry) - implied = 2; - } - } - else if (H5T__bit_get_d(s, (mpos + (size_t)bitno) - 1, (size_t)1) && denormalized) - /* For either source or destination, denormalized value doesn't increment carry.*/ - H5T__bit_inc(s, mpos + (size_t)bitno - 1, 1 + msize - (size_t)bitno); - } - else - carry = false; - - /* - * Write the mantissa to the destination - */ - if (mrsh > dst.u.f.msize + 1) { - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); - } - else if (mrsh == dst.u.f.msize + 1) { - H5T__bit_set(d, dst.u.f.mpos + 1, dst.u.f.msize - 1, false); - H5T__bit_set(d, dst.u.f.mpos, (size_t)1, true); - } - else if (mrsh == dst.u.f.msize) { - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); - H5T__bit_set_d(d, dst.u.f.mpos, MIN(2, dst.u.f.msize), (hsize_t)implied); - } - else { - if (mrsh > 0) { - H5T__bit_set(d, dst.u.f.mpos + dst.u.f.msize - mrsh, mrsh, false); - H5T__bit_set_d(d, dst.u.f.mpos + dst.u.f.msize - mrsh, (size_t)2, (hsize_t)implied); - } - if (mrsh + msize >= dst.u.f.msize) { - H5T__bit_copy(d, dst.u.f.mpos, s, (mpos + msize + mrsh - dst.u.f.msize), - dst.u.f.msize - mrsh); - } - else { - H5T__bit_copy(d, dst.u.f.mpos + dst.u.f.msize - (mrsh + msize), s, mpos, msize); - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize - (mrsh + msize), false); - } - } - - /* Write the exponent */ - if (carry) { - expo++; - if (expo >= expo_max) { - /* - * The exponent is too large to fit in the available - * region or it results in the maximum possible value. - * Use positive or negative infinity instead unless the - * application specifies something else. Before - * calling the overflow handler make sure the source - * buffer we hand it is in the original byte order. - */ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - expo = expo_max; - H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) { - reverse = false; - goto next; - } - } - } - /*reset CARRY*/ - carry = false; - - H5_CHECK_OVERFLOW(expo, hssize_t, hsize_t); - H5T__bit_set_d(d, dst.u.f.epos, dst.u.f.esize, (hsize_t)expo); - -padding: - - /* - * Set external padding areas - */ - if (dst.offset > 0) { - assert(H5T_PAD_ZERO == dst.lsb_pad || H5T_PAD_ONE == dst.lsb_pad); - H5T__bit_set(d, (size_t)0, dst.offset, (bool)(H5T_PAD_ONE == dst.lsb_pad)); - } - if (dst.offset + dst.prec != 8 * dst_p->shared->size) { - assert(H5T_PAD_ZERO == dst.msb_pad || H5T_PAD_ONE == dst.msb_pad); - H5T__bit_set(d, dst.offset + dst.prec, 8 * dst_p->shared->size - (dst.offset + dst.prec), - (bool)(H5T_PAD_ONE == dst.msb_pad)); - } - - /* - * Put the destination in the correct byte order. See note at - * beginning of loop. - */ - if (H5T_ORDER_BE == dst.order && reverse) { - half_size = dst_p->shared->size / 2; - for (i = 0; i < half_size; i++) { - uint8_t tmp = d[dst_p->shared->size - (i + 1)]; - d[dst_p->shared->size - (i + 1)] = d[i]; - d[i] = tmp; - } - } - else if (H5T_ORDER_VAX == dst.order && reverse) { - tsize = dst_p->shared->size; - assert(0 == tsize % 2); - - for (i = 0; i < tsize; i += 4) { - tmp1 = d[i]; - tmp2 = d[i + 1]; - - d[i] = d[(tsize - 2) - i]; - d[i + 1] = d[(tsize - 1) - i]; - - d[(tsize - 2) - i] = tmp1; - d[(tsize - 1) - i] = tmp2; - } - } - - /* - * If we had used a temporary buffer for the destination then we - * should copy the value to the true destination buffer. - */ -next: - if (d == dbuf) - H5MM_memcpy(dp, d, dst_p->shared->size); - - /* Advance source & destination pointers by delta amounts */ - sp += src_delta; - dp += dst_delta; - } - - break; - - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - if (src_rev) - H5MM_free(src_rev); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_f_f() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_s_s - * - * Purpose: Convert one fixed-length string type to another. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_s_s(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) -{ - ssize_t src_delta, dst_delta; /*source & destination stride */ - int direction; /*direction of traversal */ - size_t elmtno; /*element number */ - size_t olap; /*num overlapping elements */ - size_t nchars = 0; /*number of characters copied */ - uint8_t *s, *sp, *d, *dp; /*src and dst traversal pointers*/ - uint8_t *dbuf = NULL; /*temp buf for overlap converts. */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (8 * src->shared->size != src->shared->u.atomic.prec || - 8 * dst->shared->size != dst->shared->u.atomic.prec) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision"); - if (0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad offset"); - if (H5T_CSET_ASCII != src->shared->u.atomic.u.s.cset && - H5T_CSET_UTF8 != src->shared->u.atomic.u.s.cset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad source character set"); - if (H5T_CSET_ASCII != dst->shared->u.atomic.u.s.cset && - H5T_CSET_UTF8 != dst->shared->u.atomic.u.s.cset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad destination character set"); - if ((H5T_CSET_ASCII == src->shared->u.atomic.u.s.cset && - H5T_CSET_UTF8 == dst->shared->u.atomic.u.s.cset) || - (H5T_CSET_ASCII == dst->shared->u.atomic.u.s.cset && - H5T_CSET_UTF8 == src->shared->u.atomic.u.s.cset)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "The library doesn't convert between strings of ASCII and UTF"); - if (src->shared->u.atomic.u.s.pad < 0 || src->shared->u.atomic.u.s.pad >= H5T_NSTR || - dst->shared->u.atomic.u.s.pad < 0 || dst->shared->u.atomic.u.s.pad >= H5T_NSTR) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character padding"); - cdata->need_bkg = H5T_BKG_NO; - break; - - case H5T_CONV_FREE: - break; - - case H5T_CONV_CONV: - /* Get the datatypes */ - if (NULL == src || NULL == dst) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - - /* - * Do we process the values from beginning to end or vice versa? Also, - * how many of the elements have the source and destination areas - * overlapping? - */ - if (src->shared->size == dst->shared->size || buf_stride) { - /* - * When the source and destination are the same size we can do - * all the conversions in place. - */ - sp = dp = (uint8_t *)buf; - direction = 1; - olap = 0; - } - else if (src->shared->size >= dst->shared->size) { - double olapd = - ceil((double)(dst->shared->size) / (double)(src->shared->size - dst->shared->size)); - olap = (size_t)olapd; - sp = dp = (uint8_t *)buf; - direction = 1; - } - else { - double olapd = - ceil((double)(src->shared->size) / (double)(dst->shared->size - src->shared->size)); - olap = (size_t)olapd; - sp = (uint8_t *)buf + (nelmts - 1) * src->shared->size; - dp = (uint8_t *)buf + (nelmts - 1) * dst->shared->size; - direction = -1; - } - - /* - * Direction & size of buffer traversal. - */ - H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); - H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); - H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); - src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src->shared->size); - dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst->shared->size); - - /* Allocate the overlap buffer */ - if (NULL == (dbuf = (uint8_t *)H5MM_calloc(dst->shared->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for string conversion"); - - /* The conversion loop. */ - for (elmtno = 0; elmtno < nelmts; elmtno++) { - - /* - * If the source and destination buffers overlap then use a - * temporary buffer for the destination. - */ - if (direction > 0) { - s = sp; - d = elmtno < olap ? dbuf : dp; - } - else { - s = sp; - d = elmtno + olap >= nelmts ? dbuf : dp; - } -#ifndef NDEBUG - /* I don't quite trust the overlap calculations yet */ - if (src->shared->size == dst->shared->size || buf_stride) { - assert(s == d); - } - else if (d == dbuf) { - assert((dp >= sp && dp < sp + src->shared->size) || - (sp >= dp && sp < dp + dst->shared->size)); - } - else { - assert((dp < sp && dp + dst->shared->size <= sp) || - (sp < dp && sp + src->shared->size <= dp)); - } -#endif - - /* Copy characters from source to destination */ - switch (src->shared->u.atomic.u.s.pad) { - case H5T_STR_NULLTERM: - for (nchars = 0; - nchars < dst->shared->size && nchars < src->shared->size && s[nchars]; - nchars++) { - d[nchars] = s[nchars]; - } - break; - - case H5T_STR_NULLPAD: - for (nchars = 0; - nchars < dst->shared->size && nchars < src->shared->size && s[nchars]; - nchars++) { - d[nchars] = s[nchars]; - } - break; - - case H5T_STR_SPACEPAD: - nchars = src->shared->size; - while (nchars > 0 && ' ' == s[nchars - 1]) - --nchars; - nchars = MIN(dst->shared->size, nchars); - if (d != s) - H5MM_memcpy(d, s, nchars); - break; - - case H5T_STR_RESERVED_3: - case H5T_STR_RESERVED_4: - case H5T_STR_RESERVED_5: - case H5T_STR_RESERVED_6: - case H5T_STR_RESERVED_7: - case H5T_STR_RESERVED_8: - case H5T_STR_RESERVED_9: - case H5T_STR_RESERVED_10: - case H5T_STR_RESERVED_11: - case H5T_STR_RESERVED_12: - case H5T_STR_RESERVED_13: - case H5T_STR_RESERVED_14: - case H5T_STR_RESERVED_15: - case H5T_STR_ERROR: - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "source string padding method not supported"); - } /* end switch */ - - /* Terminate or pad the destination */ - switch (dst->shared->u.atomic.u.s.pad) { - case H5T_STR_NULLTERM: - while (nchars < dst->shared->size) - d[nchars++] = '\0'; - d[dst->shared->size - 1] = '\0'; - break; - - case H5T_STR_NULLPAD: - while (nchars < dst->shared->size) - d[nchars++] = '\0'; - break; - - case H5T_STR_SPACEPAD: - while (nchars < dst->shared->size) - d[nchars++] = ' '; - break; - - case H5T_STR_RESERVED_3: - case H5T_STR_RESERVED_4: - case H5T_STR_RESERVED_5: - case H5T_STR_RESERVED_6: - case H5T_STR_RESERVED_7: - case H5T_STR_RESERVED_8: - case H5T_STR_RESERVED_9: - case H5T_STR_RESERVED_10: - case H5T_STR_RESERVED_11: - case H5T_STR_RESERVED_12: - case H5T_STR_RESERVED_13: - case H5T_STR_RESERVED_14: - case H5T_STR_RESERVED_15: - case H5T_STR_ERROR: - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "destination string padding method not supported"); - } /* end switch */ - - /* - * If we used a temporary buffer for the destination then we - * should copy the value to the true destination buffer. - */ - if (d == dbuf) - H5MM_memcpy(dp, d, dst->shared->size); - - /* Advance source & destination pointers by delta amounts */ - sp += src_delta; - dp += dst_delta; - } /* end for */ - break; - - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - H5MM_xfree(dbuf); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_s_s() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_uchar - * - * Purpose: Converts `signed char' to `unsigned char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_su(SCHAR, UCHAR, signed char, unsigned char, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_schar - * - * Purpose: Converts `unsigned char' to `signed char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_us(UCHAR, SCHAR, unsigned char, signed char, -, SCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_short - * - * Purpose: Converts `signed char' to `short' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(SCHAR, SHORT, signed char, short, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_ushort - * - * Purpose: Converts `signed char' to `unsigned short' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(SCHAR, USHORT, signed char, unsigned short, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_short - * - * Purpose: Converts `unsigned char' to `short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(UCHAR, SHORT, unsigned char, short, -, SHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_ushort - * - * Purpose: Converts `unsigned char' to `unsigned short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(UCHAR, USHORT, unsigned char, unsigned short, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_int - * - * Purpose: Converts `signed char' to `int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(SCHAR, INT, signed char, int, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_uint - * - * Purpose: Converts `signed char' to `unsigned int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(SCHAR, UINT, signed char, unsigned, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_int - * - * Purpose: Converts `unsigned char' to `int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(UCHAR, INT, unsigned char, int, -, INT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_uint - * - * Purpose: Converts `unsigned char' to `unsigned int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(UCHAR, UINT, unsigned char, unsigned, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_long - * - * Purpose: Converts `signed char' to `long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(SCHAR, LONG, signed char, long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_ulong - * - * Purpose: Converts `signed char' to `unsigned long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(SCHAR, ULONG, signed char, unsigned long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_long - * - * Purpose: Converts `unsigned char' to `long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(UCHAR, LONG, unsigned char, long, -, LONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_ulong - * - * Purpose: Converts `unsigned char' to `unsigned long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(UCHAR, ULONG, unsigned char, unsigned long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_llong - * - * Purpose: Converts `signed char' to `long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(SCHAR, LLONG, signed char, long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_ullong - * - * Purpose: Converts `signed char' to `unsigned long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(SCHAR, ULLONG, signed char, unsigned long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_llong - * - * Purpose: Converts `unsigned char' to `long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(UCHAR, LLONG, unsigned char, long long, -, LLONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_ullong - * - * Purpose: Converts `unsigned char' to `unsigned long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(UCHAR, ULLONG, unsigned char, unsigned long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_schar - * - * Purpose: Converts `short' to `signed char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(SHORT, SCHAR, short, signed char, SCHAR_MIN, SCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_uchar - * - * Purpose: Converts `short' to `unsigned char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(SHORT, UCHAR, short, unsigned char, -, UCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_schar - * - * Purpose: Converts `unsigned short' to `signed char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(USHORT, SCHAR, unsigned short, signed char, -, SCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_uchar - * - * Purpose: Converts `unsigned short' to `unsigned char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(USHORT, UCHAR, unsigned short, unsigned char, -, UCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_ushort - * - * Purpose: Converts `short' to `unsigned short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_su(SHORT, USHORT, short, unsigned short, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_short - * - * Purpose: Converts `unsigned short' to `short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_us(USHORT, SHORT, unsigned short, short, -, SHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_int - * - * Purpose: Converts `short' to `int' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(SHORT, INT, short, int, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_uint - * - * Purpose: Converts `short' to `unsigned int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(SHORT, UINT, short, unsigned, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_int - * - * Purpose: Converts `unsigned short' to `int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(USHORT, INT, unsigned short, int, -, INT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_uint - * - * Purpose: Converts `unsigned short' to `unsigned int' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(USHORT, UINT, unsigned short, unsigned, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_long - * - * Purpose: Converts `short' to `long' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(SHORT, LONG, short, long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_ulong - * - * Purpose: Converts `short' to `unsigned long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(SHORT, ULONG, short, unsigned long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_long - * - * Purpose: Converts `unsigned short' to `long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(USHORT, LONG, unsigned short, long, -, LONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_ulong - * - * Purpose: Converts `unsigned short' to `unsigned long' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(USHORT, ULONG, unsigned short, unsigned long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_llong - * - * Purpose: Converts `short' to `long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(SHORT, LLONG, short, long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_ullong - * - * Purpose: Converts `short' to `unsigned long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(SHORT, ULLONG, short, unsigned long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_llong - * - * Purpose: Converts `unsigned short' to `long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(USHORT, LLONG, unsigned short, long long, -, LLONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_ullong - * - * Purpose: Converts `unsigned short' to `unsigned long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(USHORT, ULLONG, unsigned short, unsigned long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_schar - * - * Purpose: Converts `int' to `signed char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(INT, SCHAR, int, signed char, SCHAR_MIN, SCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_uchar - * - * Purpose: Converts `int' to `unsigned char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(INT, UCHAR, int, unsigned char, -, UCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_schar - * - * Purpose: Converts `unsigned int' to `signed char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(UINT, SCHAR, unsigned, signed char, -, SCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_uchar - * - * Purpose: Converts `unsigned int' to `unsigned char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(UINT, UCHAR, unsigned, unsigned char, -, UCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_short - * - * Purpose: Converts `int' to `short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(INT, SHORT, int, short, SHRT_MIN, SHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_ushort - * - * Purpose: Converts `int' to `unsigned short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(INT, USHORT, int, unsigned short, -, USHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_short - * - * Purpose: Converts `unsigned int' to `short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(UINT, SHORT, unsigned, short, -, SHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_ushort - * - * Purpose: Converts `unsigned int' to `unsigned short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(UINT, USHORT, unsigned, unsigned short, -, USHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_uint - * - * Purpose: Converts `int' to `unsigned int' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_su(INT, UINT, int, unsigned, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_int - * - * Purpose: Converts `unsigned int' to `int' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_us(UINT, INT, unsigned, int, -, INT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_long - * - * Purpose: Converts `int' to `long' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(INT, LONG, int, long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_ulong - * - * Purpose: Converts `int' to `unsigned long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(INT, LONG, int, unsigned long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_long - * - * Purpose: Converts `unsigned int' to `long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(UINT, LONG, unsigned, long, -, LONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_ulong - * - * Purpose: Converts `unsigned int' to `unsigned long' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(UINT, ULONG, unsigned, unsigned long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_llong - * - * Purpose: Converts `int' to `long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(INT, LLONG, int, long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_ullong - * - * Purpose: Converts `int' to `unsigned long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(INT, ULLONG, int, unsigned long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_llong - * - * Purpose: Converts `unsigned int' to `long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(UINT, LLONG, unsigned, long long, -, LLONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_ullong - * - * Purpose: Converts `unsigned int' to `unsigned long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(UINT, ULLONG, unsigned, unsigned long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_schar - * - * Purpose: Converts `long' to `signed char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(LONG, SCHAR, long, signed char, SCHAR_MIN, SCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_uchar - * - * Purpose: Converts `long' to `unsigned char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(LONG, UCHAR, long, unsigned char, -, UCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_schar - * - * Purpose: Converts `unsigned long' to `signed char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(ULONG, SCHAR, unsigned long, signed char, -, SCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_uchar - * - * Purpose: Converts `unsigned long' to `unsigned char' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(ULONG, UCHAR, unsigned long, unsigned char, -, UCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_short - * - * Purpose: Converts `long' to `short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(LONG, SHORT, long, short, SHRT_MIN, SHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_ushort - * - * Purpose: Converts `long' to `unsigned short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(LONG, USHORT, long, unsigned short, -, USHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_short - * - * Purpose: Converts `unsigned long' to `short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(ULONG, SHORT, unsigned long, short, -, SHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_ushort - * - * Purpose: Converts `unsigned long' to `unsigned short' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(ULONG, USHORT, unsigned long, unsigned short, -, USHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_int - * - * Purpose: Converts `long' to `int' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(LONG, INT, long, int, INT_MIN, INT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_uint - * - * Purpose: Converts `long' to `unsigned int' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(LONG, UINT, long, unsigned, -, UINT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_int - * - * Purpose: Converts `unsigned long' to `int' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(ULONG, INT, unsigned long, int, -, INT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_uint - * - * Purpose: Converts `unsigned long' to `unsigned int' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(ULONG, UINT, unsigned long, unsigned, -, UINT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_ulong - * - * Purpose: Converts `long' to `unsigned long' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_su(LONG, ULONG, long, unsigned long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_long - * - * Purpose: Converts `unsigned long' to `long' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_us(ULONG, LONG, unsigned long, long, -, LONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_llong - * - * Purpose: Converts `long' to `long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sS(LONG, LLONG, long, long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_ullong - * - * Purpose: Converts `long' to `unsigned long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_sU(LONG, ULLONG, long, unsigned long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_llong - * - * Purpose: Converts `unsigned long' to `long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uS(ULONG, LLONG, unsigned long, long long, -, LLONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_ullong - * - * Purpose: Converts `unsigned long' to `unsigned long long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_uU(ULONG, ULLONG, unsigned long, unsigned long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_schar - * - * Purpose: Converts `long long' to `signed char' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(LLONG, SCHAR, long long, signed char, SCHAR_MIN, SCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_uchar - * - * Purpose: Converts `long long' to `unsigned char' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(LLONG, UCHAR, long long, unsigned char, -, UCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_schar - * - * Purpose: Converts `unsigned long long' to `signed char' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(ULLONG, SCHAR, unsigned long long, signed char, -, SCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_uchar - * - * Purpose: Converts `unsigned long long' to `unsigned char' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(ULLONG, UCHAR, unsigned long long, unsigned char, -, UCHAR_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_short - * - * Purpose: Converts `long long' to `short' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(LLONG, SHORT, long long, short, SHRT_MIN, SHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_ushort - * - * Purpose: Converts `long long' to `unsigned short' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(LLONG, USHORT, long long, unsigned short, -, USHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_short - * - * Purpose: Converts `unsigned long long' to `short' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(ULLONG, SHORT, unsigned long long, short, -, SHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_ushort - * - * Purpose: Converts `unsigned long long' to `unsigned short' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(ULLONG, USHORT, unsigned long long, unsigned short, -, USHRT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_int - * - * Purpose: Converts `long long' to `int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(LLONG, INT, long long, int, INT_MIN, INT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_uint - * - * Purpose: Converts `long long' to `unsigned int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(LLONG, UINT, long long, unsigned, -, UINT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_int - * - * Purpose: Converts `unsigned long long' to `int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(ULLONG, INT, unsigned long long, int, -, INT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_uint - * - * Purpose: Converts `unsigned long long' to `unsigned int' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(ULLONG, UINT, unsigned long long, unsigned, -, UINT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_long - * - * Purpose: Converts `long long' to `long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ss(LLONG, LONG, long long, long, LONG_MIN, LONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_ulong - * - * Purpose: Converts `long long' to `unsigned long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Su(LLONG, ULONG, long long, unsigned long, -, ULONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_long - * - * Purpose: Converts `unsigned long long' to `long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Us(ULLONG, LONG, unsigned long long, long, -, LONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_ulong - * - * Purpose: Converts `unsigned long long' to `unsigned long' - * - * Return: Success: Non-negative - * - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Uu(ULLONG, ULONG, unsigned long long, unsigned long, -, ULONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_ullong - * - * Purpose: Converts `long long' to `unsigned long long' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_su(LLONG, ULLONG, long long, unsigned long long, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_llong - * - * Purpose: Converts `unsigned long long' to `long long' - * - * Return: Success: non-negative - * - * Failure: negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_us(ULLONG, LLONG, unsigned long long, long long, -, LLONG_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_double - * - * Purpose: Convert native `float' to native `double' using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fF(FLOAT, DOUBLE, float, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_ldouble - * - * Purpose: Convert native `float' to native `long double' using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fF(FLOAT, LDOUBLE, float, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_float - * - * Purpose: Convert native `double' to native `float' using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ff(DOUBLE, FLOAT, double, float, -FLT_MAX, FLT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_ldouble - * - * Purpose: Convert native `double' to native `long double' using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fF(DOUBLE, LDOUBLE, double, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_float - * - * Purpose: Convert native `long double' to native `float' using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ff(LDOUBLE, FLOAT, long double, float, -FLT_MAX, FLT_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_double - * - * Purpose: Convert native `long double' to native `double' using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_Ff(LDOUBLE, DOUBLE, long double, double, -DBL_MAX, DBL_MAX); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_float - * - * Purpose: Convert native signed char to native float using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(SCHAR, FLOAT, signed char, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_double - * - * Purpose: Convert native signed char to native double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(SCHAR, DOUBLE, signed char, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_schar_ldouble - * - * Purpose: Convert native signed char to native long double using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_schar_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(SCHAR, LDOUBLE, signed char, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_float - * - * Purpose: Convert native unsigned char to native float using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(UCHAR, FLOAT, unsigned char, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_double - * - * Purpose: Convert native unsigned char to native double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(UCHAR, DOUBLE, unsigned char, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_ldouble - * - * Purpose: Convert native unsigned char to native long double using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uchar_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(UCHAR, LDOUBLE, unsigned char, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_float - * - * Purpose: Convert native short to native float using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(SHORT, FLOAT, short, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_double - * - * Purpose: Convert native short to native double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(SHORT, DOUBLE, short, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_short_ldouble - * - * Purpose: Convert native short to native long double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_short_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(SHORT, LDOUBLE, short, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_float - * - * Purpose: Convert native unsigned short to native float using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(USHORT, FLOAT, unsigned short, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_double - * - * Purpose: Convert native unsigned short to native double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(USHORT, DOUBLE, unsigned short, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_ldouble - * - * Purpose: Convert native unsigned short to native long double using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ushort_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(USHORT, LDOUBLE, unsigned short, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_float - * - * Purpose: Convert native integer to native float using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(INT, FLOAT, int, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_double - * - * Purpose: Convert native integer to native double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(INT, DOUBLE, int, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_int_ldouble - * - * Purpose: Convert native integer to native long double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_int_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(INT, LDOUBLE, int, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_float - * - * Purpose: Convert native unsigned integer to native float using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(UINT, FLOAT, unsigned int, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_double - * - * Purpose: Convert native unsigned integer to native double using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(UINT, DOUBLE, unsigned int, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_uint_ldouble - * - * Purpose: Convert native unsigned integer to native long double using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_uint_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(UINT, LDOUBLE, unsigned int, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_float - * - * Purpose: Convert native long to native float using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(LONG, FLOAT, long, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_double - * - * Purpose: Convert native long to native double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(LONG, DOUBLE, long, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_long_ldouble - * - * Purpose: Convert native long to native long double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_long_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(LONG, LDOUBLE, long, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_float - * - * Purpose: Convert native unsigned long to native float using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(ULONG, FLOAT, unsigned long, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_double - * - * Purpose: Convert native unsigned long to native double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(ULONG, DOUBLE, unsigned long, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_ldouble - * - * Purpose: Convert native unsigned long to native long double using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ulong_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(ULONG, LDOUBLE, unsigned long, long double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_float - * - * Purpose: Convert native long long to native float using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(LLONG, FLOAT, long long, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_double - * - * Purpose: Convert native long long to native double using hardware. - * This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_llong_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(LLONG, DOUBLE, long long, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_llong_ldouble - * - * Purpose: Convert native long long to native long double using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -#ifdef H5T_CONV_INTERNAL_LLONG_LDOUBLE -herr_t -H5T__conv_llong_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(LLONG, LDOUBLE, long long, long double, -, -); -} -#endif /* H5T_CONV_INTERNAL_LLONG_LDOUBLE */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_float - * - * Purpose: Convert native unsigned long long to native float using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(ULLONG, FLOAT, unsigned long long, float, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_double - * - * Purpose: Convert native unsigned long long to native double using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ullong_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(ULLONG, DOUBLE, unsigned long long, double, -, -); -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_ldouble - * - * Purpose: Convert native unsigned long long to native long double using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -#ifdef H5T_CONV_INTERNAL_ULLONG_LDOUBLE -herr_t -H5T__conv_ullong_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(ULLONG, LDOUBLE, unsigned long long, long double, -, -); -} -#endif /*H5T_CONV_INTERNAL_ULLONG_LDOUBLE*/ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_schar - * - * Purpose: Convert native float to native signed char using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, SCHAR, float, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_uchar - * - * Purpose: Convert native float to native unsigned char using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, UCHAR, float, unsigned char, 0, UCHAR_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_schar - * - * Purpose: Convert native double to native signed char using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, SCHAR, double, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_uchar - * - * Purpose: Convert native double to native unsigned char using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, UCHAR, double, unsigned char, 0, UCHAR_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_schar - * - * Purpose: Convert native long double to native signed char using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, SCHAR, long double, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_uchar - * - * Purpose: Convert native long double to native unsigned char using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, UCHAR, long double, unsigned char, 0, UCHAR_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_short - * - * Purpose: Convert native float to native short using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, SHORT, float, short, SHRT_MIN, SHRT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_ushort - * - * Purpose: Convert native float to native unsigned short using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, USHORT, float, unsigned short, 0, USHRT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_short - * - * Purpose: Convert native double to native short using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, SHORT, double, short, SHRT_MIN, SHRT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_ushort - * - * Purpose: Convert native double to native unsigned short using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, USHORT, double, unsigned short, 0, USHRT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_short - * - * Purpose: Convert native long double to native short using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, SHORT, long double, short, SHRT_MIN, SHRT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_ushort - * - * Purpose: Convert native long double to native unsigned short using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, USHORT, long double, unsigned short, 0, USHRT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_int - * - * Purpose: Convert native float to native int using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, INT, float, int, INT_MIN, INT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_uint - * - * Purpose: Convert native float to native unsigned int using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, UINT, float, unsigned int, 0, UINT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_int - * - * Purpose: Convert native double to native int using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, INT, double, int, INT_MIN, INT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_uint - * - * Purpose: Convert native double to native unsigned int using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, UINT, double, unsigned int, 0, UINT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_int - * - * Purpose: Convert native long double to native int using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, INT, long double, int, INT_MIN, INT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_uint - * - * Purpose: Convert native long double to native unsigned int using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, UINT, long double, unsigned int, 0, UINT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_long - * - * Purpose: Convert native float to native long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, LONG, float, long, LONG_MIN, LONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_ulong - * - * Purpose: Convert native float to native unsigned long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, ULONG, float, unsigned long, 0, ULONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_long - * - * Purpose: Convert native double to native long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, LONG, double, long, LONG_MIN, LONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_ulong - * - * Purpose: Convert native double to native unsigned long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, ULONG, double, unsigned long, 0, ULONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_long - * - * Purpose: Convert native long double to native long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, LONG, long double, long, LONG_MIN, LONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_ulong - * - * Purpose: Convert native long double to native unsigned long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_ldouble_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, ULONG, long double, unsigned long, 0, ULONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_llong - * - * Purpose: Convert native float to native long long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, LLONG, float, long long, LLONG_MIN, LLONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_float_ullong - * - * Purpose: Convert native float to native unsigned long long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_float_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT, ULLONG, float, unsigned long long, 0, ULLONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_llong - * - * Purpose: Convert native double to native long long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, LLONG, double, long long, LLONG_MIN, LLONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_double_ullong - * - * Purpose: Convert native double to native unsigned long long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_double_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(DOUBLE, ULLONG, double, unsigned long long, 0, ULLONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_llong - * - * Purpose: Convert native long double to native long long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -#ifdef H5T_CONV_INTERNAL_LDOUBLE_LLONG -herr_t -H5T__conv_ldouble_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, LLONG, long double, long long, LLONG_MIN, LLONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} -#endif /*H5T_CONV_INTERNAL_LDOUBLE_LLONG*/ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_ullong - * - * Purpose: Convert native long double to native unsigned long long using - * hardware. This is a fast special case. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -#ifdef H5T_CONV_INTERNAL_LDOUBLE_ULLONG -herr_t -H5T__conv_ldouble_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(LDOUBLE, ULLONG, long double, unsigned long long, 0, ULLONG_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} -#endif /*H5T_CONV_INTERNAL_LDOUBLE_ULLONG*/ - -/* Conversions for _Float16 type */ -#ifdef H5_HAVE__FLOAT16 -herr_t -H5T__conv_schar__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(SCHAR, FLOAT16, signed char, H5__Float16, -, -); -} - -herr_t -H5T__conv_uchar__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(UCHAR, FLOAT16, unsigned char, H5__Float16, -, -); -} - -herr_t -H5T__conv_short__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_xF(SHORT, FLOAT16, short, H5__Float16, -, -); -} - -herr_t -H5T__conv_ushort__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Xf(USHORT, FLOAT16, unsigned short, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} - -herr_t -H5T__conv_int__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Xf(INT, FLOAT16, int, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} - -herr_t -H5T__conv_uint__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Xf(UINT, FLOAT16, unsigned int, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} - -herr_t -H5T__conv_long__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Xf(LONG, FLOAT16, long, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} - -herr_t -H5T__conv_ulong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Xf(ULONG, FLOAT16, unsigned long, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} - -herr_t -H5T__conv_llong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Xf(LLONG, FLOAT16, long long, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} - -herr_t -H5T__conv_ullong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Xf(ULLONG, FLOAT16, unsigned long long, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} - -herr_t -H5T__conv_float__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Ff(FLOAT, FLOAT16, float, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} - -herr_t -H5T__conv_double__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Ff(DOUBLE, FLOAT16, double, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} - -#ifdef H5T_CONV_INTERNAL_LDOUBLE_FLOAT16 -herr_t -H5T__conv_ldouble__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) -{ - /* Suppress warning about non-standard floating-point literal suffix */ - H5_GCC_CLANG_DIAG_OFF("pedantic") - H5T_CONV_Ff(LDOUBLE, FLOAT16, long double, H5__Float16, -FLT16_MAX, FLT16_MAX); - H5_GCC_CLANG_DIAG_ON("pedantic") -} -#endif - -herr_t -H5T__conv__Float16_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT16, SCHAR, H5__Float16, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -herr_t -H5T__conv__Float16_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT16, UCHAR, H5__Float16, unsigned char, 0, UCHAR_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -herr_t -H5T__conv__Float16_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5_GCC_CLANG_DIAG_OFF("float-equal") - H5T_CONV_Fx(FLOAT16, SHORT, H5__Float16, short, SHRT_MIN, SHRT_MAX); - H5_GCC_CLANG_DIAG_ON("float-equal") -} - -herr_t -H5T__conv__Float16_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fX(FLOAT16, USHORT, H5__Float16, unsigned short, 0, USHRT_MAX); -} - -herr_t -H5T__conv__Float16_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fX(FLOAT16, INT, H5__Float16, int, INT_MIN, INT_MAX); -} - -herr_t -H5T__conv__Float16_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fX(FLOAT16, UINT, H5__Float16, unsigned int, 0, UINT_MAX); -} - -herr_t -H5T__conv__Float16_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fX(FLOAT16, LONG, H5__Float16, long, LONG_MIN, LONG_MAX); -} - -herr_t -H5T__conv__Float16_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fX(FLOAT16, ULONG, H5__Float16, unsigned long, 0, ULONG_MAX); -} - -herr_t -H5T__conv__Float16_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fX(FLOAT16, LLONG, H5__Float16, long long, LLONG_MIN, LLONG_MAX); -} - -herr_t -H5T__conv__Float16_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fX(FLOAT16, ULLONG, H5__Float16, unsigned long long, 0, ULLONG_MAX); -} - -herr_t -H5T__conv__Float16_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fF(FLOAT16, FLOAT, H5__Float16, float, -, -); -} - -herr_t -H5T__conv__Float16_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fF(FLOAT16, DOUBLE, H5__Float16, double, -, -); -} - -herr_t -H5T__conv__Float16_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) -{ - H5T_CONV_fF(FLOAT16, LDOUBLE, H5__Float16, long double, -, -); -} -#endif - -/*------------------------------------------------------------------------- - * Function: H5T__conv_f_i - * - * Purpose: Convert one floating-point type to an integer. This is - * the catch-all function for float-integer conversions and - * is probably not particularly fast. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_f_i(const H5T_t *src_p, const H5T_t *dst_p, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - /* Traversal-related variables */ - H5T_atomic_t src; /*atomic source info */ - H5T_atomic_t dst; /*atomic destination info */ - int direction; /*forward or backward traversal */ - size_t elmtno; /*element number */ - size_t half_size; /*half the type size */ - size_t tsize; /*type size for swapping bytes */ - size_t olap; /*num overlapping elements */ - uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t *src_rev = NULL; /*order-reversed source buffer */ - uint8_t dbuf[64] = {0}; /*temp destination buffer */ - uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ - - /* Conversion-related variables */ - hssize_t expo; /*source exponent */ - hssize_t sign; /*source sign bit value */ - uint8_t *int_buf = NULL; /*buffer for temporary value */ - size_t buf_size; /*buffer size for temporary value */ - size_t i; /*miscellaneous counters */ - ssize_t msb_pos_s; /*first bit(MSB) in an integer */ - ssize_t new_msb_pos; /*MSB position after shifting mantissa by exponent */ - hssize_t shift_val; /*shift value when shifting mantissa by exponent */ - bool truncated; /*if fraction value is dropped */ - bool reverse; /*if reverse order of destination at the end */ - H5T_conv_ret_t except_ret; /*return of callback function */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - if (NULL == src_p || NULL == dst_p) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - src = src_p->shared->u.atomic; - dst = dst_p->shared->u.atomic; - if (H5T_ORDER_LE != src.order && H5T_ORDER_BE != src.order && H5T_ORDER_VAX != src.order) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst_p->shared->size > sizeof(dbuf)) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - if (8 * sizeof(expo) - 1 < src.u.f.esize) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); - cdata->need_bkg = H5T_BKG_NO; - break; - - case H5T_CONV_FREE: - break; - - case H5T_CONV_CONV: - if (NULL == src_p || NULL == dst_p) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - - src = src_p->shared->u.atomic; - dst = dst_p->shared->u.atomic; - - /* - * Do we process the values from beginning to end or vice versa? Also, - * how many of the elements have the source and destination areas - * overlapping? - */ - if (src_p->shared->size == dst_p->shared->size || buf_stride) { - sp = dp = (uint8_t *)buf; - direction = 1; - olap = nelmts; - } - else if (src_p->shared->size >= dst_p->shared->size) { - double olap_d = - ceil((double)(dst_p->shared->size) / (double)(src_p->shared->size - dst_p->shared->size)); - olap = (size_t)olap_d; - sp = dp = (uint8_t *)buf; - direction = 1; - } - else { - double olap_d = - ceil((double)(src_p->shared->size) / (double)(dst_p->shared->size - src_p->shared->size)); - olap = (size_t)olap_d; - sp = (uint8_t *)buf + (nelmts - 1) * src_p->shared->size; - dp = (uint8_t *)buf + (nelmts - 1) * dst_p->shared->size; - direction = -1; - } - - /* Allocate enough space for the buffer holding temporary - * converted value - */ - if (dst.prec / 8 > src_p->shared->size) - buf_size = (dst.prec + 7) / 8; - else - buf_size = src_p->shared->size; - int_buf = (uint8_t *)H5MM_calloc(buf_size); - - /* Allocate space for order-reversed source buffer */ - src_rev = (uint8_t *)H5MM_calloc(src_p->shared->size); - - /* The conversion loop */ - for (elmtno = 0; elmtno < nelmts; elmtno++) { - /* Set these variables to default */ - except_ret = H5T_CONV_UNHANDLED; - truncated = false; - reverse = true; - - /* - * If the source and destination buffers overlap then use a - * temporary buffer for the destination. - */ - if (direction > 0) { - s = sp; - d = elmtno < olap ? dbuf : dp; - } - else { - s = sp; - d = elmtno + olap >= nelmts ? dbuf : dp; - } -#ifndef NDEBUG - /* I don't quite trust the overlap calculations yet */ - if (d == dbuf) { - assert((dp >= sp && dp < sp + src_p->shared->size) || - (sp >= dp && sp < dp + dst_p->shared->size)); - } - else { - assert((dp < sp && dp + dst_p->shared->size <= sp) || - (sp < dp && sp + src_p->shared->size <= dp)); - } -#endif - /* - * Put the data in little endian order so our loops aren't so - * complicated. We'll do all the conversion stuff assuming - * little endian and then we'll fix the order at the end. - */ - if (H5T_ORDER_BE == src.order) { - half_size = src_p->shared->size / 2; - for (i = 0; i < half_size; i++) { - tmp1 = s[src_p->shared->size - (i + 1)]; - s[src_p->shared->size - (i + 1)] = s[i]; - s[i] = tmp1; - } - } - else if (H5T_ORDER_VAX == src.order) { - tsize = src_p->shared->size; - assert(0 == tsize % 2); - - for (i = 0; i < tsize; i += 4) { - tmp1 = s[i]; - tmp2 = s[i + 1]; - - s[i] = s[(tsize - 2) - i]; - s[i + 1] = s[(tsize - 1) - i]; - - s[(tsize - 2) - i] = tmp1; - s[(tsize - 1) - i] = tmp2; - } - } - - /*zero-set all destination bits*/ - H5T__bit_set(d, dst.offset, dst.prec, false); - - /* - * Find the sign bit value of the source. - */ - sign = (hssize_t)H5T__bit_get_d(s, src.u.f.sign, (size_t)1); - - /* - * Check for special cases: +0, -0, +Inf, -Inf, NaN - */ - if (H5T__bit_find(s, src.u.f.mpos, src.u.f.msize, H5T_BIT_LSB, true) < 0) { - if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, true) < 0) { - /* +0 or -0 */ - /* Set all bits to zero */ - goto padding; - } - else if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { - /* +Infinity or -Infinity */ - if (sign) { /* -Infinity */ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_NINF, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - if (H5T_SGN_2 == dst.u.i.sign) - H5T__bit_set(d, dst.prec - 1, (size_t)1, true); - } - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - } - else { /* +Infinity */ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_PINF, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - if (H5T_SGN_NONE == dst.u.i.sign) - H5T__bit_set(d, dst.offset, dst.prec, true); - else if (H5T_SGN_2 == dst.u.i.sign) - H5T__bit_set(d, dst.offset, dst.prec - 1, true); - } - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - } - goto padding; - } - } - else if (H5T_NORM_NONE == src.u.f.norm && - H5T__bit_find(s, src.u.f.mpos, src.u.f.msize - 1, H5T_BIT_LSB, true) < 0 && - H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { - /*This is a special case for the source of no implied mantissa bit. - *If the exponent bits are all 1s and only the 1st bit of mantissa - *is set to 1. It's infinity. The Intel-Linux "long double" is this case.*/ - /* +Infinity or -Infinity */ - if (sign) { /* -Infinity */ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_NINF, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - if (H5T_SGN_2 == dst.u.i.sign) - H5T__bit_set(d, dst.prec - 1, (size_t)1, true); - } - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - } - else { /* +Infinity */ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_PINF, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - if (H5T_SGN_NONE == dst.u.i.sign) - H5T__bit_set(d, dst.offset, dst.prec, true); - else if (H5T_SGN_2 == dst.u.i.sign) - H5T__bit_set(d, dst.offset, dst.prec - 1, true); - } - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - } - goto padding; - } - else if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { - /* NaN */ - if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_NAN, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, - src_rev, d, conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - /*Just set all bits to zero.*/ - goto padding; - } - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); - - goto padding; - } - - /* - * Get the exponent as an unsigned quantity from the section of - * the source bit field where it's located. Not expecting - * exponent to be greater than the maximal value of hssize_t. - */ - expo = (hssize_t)H5T__bit_get_d(s, src.u.f.epos, src.u.f.esize); - - /* - * Calculate the true source exponent by adjusting according to - * the source exponent bias. - */ - if (0 == expo || H5T_NORM_NONE == src.u.f.norm) { - expo -= (hssize_t)(src.u.f.ebias - 1); - } - else if (H5T_NORM_IMPLIED == src.u.f.norm) { - expo -= (hssize_t)src.u.f.ebias; - } - else { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "normalization method not implemented yet"); - } - - /* - * Get the mantissa as bit vector from the section of - * the source bit field where it's located. - * Keep the little-endian order in the buffer. - * A sequence 0x01020304 will be like in the buffer, - * 04 03 02 01 - * | | | | - * V V V V - * buf[0] buf[1] buf[2] buf[3] - */ - H5T__bit_copy(int_buf, (size_t)0, s, src.u.f.mpos, src.u.f.msize); - - /* - * Restore the implicit bit for mantissa if it's implied. - * Equivalent to mantissa |= (hsize_t)1<u.conv.cb_struct.func) - truncated = true; - - if (H5T_SGN_NONE == dst.u.i.sign) { /*destination is unsigned*/ - /* - * Destination is unsigned. Library's default way: If the source value - * is greater than the maximal destination value then it overflows, the - * destination will be set to the maximum possible value. When the - * source is negative, underflow happens. Set the destination to be - * zero(do nothing). If user's exception handler is set, call it and - * let user handle it. - */ - if (sign) { /*source is negative*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - } - } - else { /*source is positive*/ - if (new_msb_pos >= (ssize_t)dst.prec) { - /*overflow*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) - H5T__bit_set(d, dst.offset, dst.prec, true); - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - } - else { - if (truncated && conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - /*copy source value into it if case is ignored by user handler*/ - if (new_msb_pos >= 0) - H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, (size_t)new_msb_pos + 1); - } - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - } - } - } - else if (H5T_SGN_2 == dst.u.i.sign) { /*Destination is signed*/ - if (sign) { /*source is negative*/ - if ((new_msb_pos >= 0) && ((size_t)new_msb_pos < dst.prec - 1)) { - if (truncated && conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { /*If this case ignored by user handler*/ - /*Convert to integer representation. Equivalent to ~(value - 1).*/ - H5T__bit_dec(int_buf, (size_t)0, dst.prec); - H5T__bit_neg(int_buf, (size_t)0, dst.prec); - - /*copy source value into destination*/ - H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, dst.prec - 1); - H5T__bit_set(d, (dst.offset + dst.prec - 1), (size_t)1, true); - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - } - else { - /* if underflows and no callback, do nothing except turn on - * the sign bit because 0x80...00 is the biggest negative value. - */ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) - H5T__bit_set(d, (dst.offset + dst.prec - 1), (size_t)1, true); - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - } - } - else { /*source is positive*/ - if (new_msb_pos >= (ssize_t)dst.prec - 1) { - /*overflow*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) - H5T__bit_set(d, dst.offset, dst.prec - 1, true); - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - } - else if (new_msb_pos < (ssize_t)dst.prec - 1) { - if (truncated && conv_ctx->u.conv.cb_struct - .func) { /*If user's exception handler is present, use it*/ - /*reverse order first*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, - conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_UNHANDLED) { - /*copy source value into it if case is ignored by user handler*/ - if (new_msb_pos >= 0) - H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, (size_t)new_msb_pos + 1); - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) { - /*No need to reverse the order of destination because user handles it*/ - reverse = false; - goto next; - } - } - } - } - -padding: - /* - * Set padding areas in destination. - */ - if (dst.offset > 0) { - assert(H5T_PAD_ZERO == dst.lsb_pad || H5T_PAD_ONE == dst.lsb_pad); - H5T__bit_set(d, (size_t)0, dst.offset, (bool)(H5T_PAD_ONE == dst.lsb_pad)); - } - if (dst.offset + dst.prec != 8 * dst_p->shared->size) { - assert(H5T_PAD_ZERO == dst.msb_pad || H5T_PAD_ONE == dst.msb_pad); - H5T__bit_set(d, dst.offset + dst.prec, 8 * dst_p->shared->size - (dst.offset + dst.prec), - (bool)(H5T_PAD_ONE == dst.msb_pad)); - } - - /* - * Put the destination in the correct byte order. See note at - * beginning of loop. - */ - if (H5T_ORDER_BE == dst.order && reverse) { - half_size = dst_p->shared->size / 2; - for (i = 0; i < half_size; i++) { - tmp1 = d[dst_p->shared->size - (i + 1)]; - d[dst_p->shared->size - (i + 1)] = d[i]; - d[i] = tmp1; - } - } - -next: - /* - * If we had used a temporary buffer for the destination then we - * should copy the value to the true destination buffer. - */ - if (d == dbuf) - H5MM_memcpy(dp, d, dst_p->shared->size); - if (buf_stride) { - sp += direction * (ssize_t)buf_stride; - dp += direction * (ssize_t)buf_stride; - } - else { - sp += direction * (ssize_t)src_p->shared->size; - dp += direction * (ssize_t)dst_p->shared->size; - } - - memset(int_buf, 0, buf_size); - } - - break; - - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - if (int_buf) - H5MM_xfree(int_buf); - if (src_rev) - H5MM_free(src_rev); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_f_i() */ - -/*------------------------------------------------------------------------- - * Function: H5T__conv_i_f - * - * Purpose: Convert one integer type to a floating-point type. This is - * the catch-all function for integer-float conversions and - * is probably not particularly fast. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T__conv_i_f(const H5T_t *src_p, const H5T_t *dst_p, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, - size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, - void H5_ATTR_UNUSED *bkg) -{ - /* Traversal-related variables */ - H5T_atomic_t src; /*atomic source info */ - H5T_atomic_t dst; /*atomic destination info */ - int direction; /*forward or backward traversal */ - size_t elmtno; /*element number */ - size_t half_size; /*half the type size */ - size_t tsize; /*type size for swapping bytes */ - size_t olap; /*num overlapping elements */ - uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t *src_rev = NULL; /*order-reversed source buffer */ - uint8_t dbuf[64] = {0}; /*temp destination buffer */ - uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ - - /* Conversion-related variables */ - hsize_t expo; /*destination exponent */ - hsize_t expo_max; /*maximal possible exponent value */ - size_t sign; /*source sign bit value */ - bool is_max_neg; /*source is maximal negative value*/ - bool do_round; /*whether there is roundup */ - uint8_t *int_buf = NULL; /*buffer for temporary value */ - size_t buf_size; /*buffer size for temporary value */ - size_t i; /*miscellaneous counters */ - size_t first; /*first bit(MSB) in an integer */ - ssize_t sfirst; /*a signed version of `first' */ - H5T_conv_ret_t except_ret; /*return of callback function */ - bool reverse; /*if reverse the order of destination */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - switch (cdata->command) { - case H5T_CONV_INIT: - if (NULL == src_p || NULL == dst_p) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - src = src_p->shared->u.atomic; - dst = dst_p->shared->u.atomic; - if (H5T_ORDER_LE != dst.order && H5T_ORDER_BE != dst.order && H5T_ORDER_VAX != dst.order) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst_p->shared->size > sizeof(dbuf)) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - if (8 * sizeof(expo) - 1 < src.u.f.esize) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); - cdata->need_bkg = H5T_BKG_NO; - break; - - case H5T_CONV_FREE: - break; - - case H5T_CONV_CONV: - if (NULL == src_p || NULL == dst_p) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (NULL == conv_ctx) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); - - src = src_p->shared->u.atomic; - dst = dst_p->shared->u.atomic; - - /* - * Do we process the values from beginning to end or vice versa? Also, - * how many of the elements have the source and destination areas - * overlapping? - */ - if (src_p->shared->size == dst_p->shared->size || buf_stride) { - sp = dp = (uint8_t *)buf; - direction = 1; - olap = nelmts; - } - else if (src_p->shared->size >= dst_p->shared->size) { - double olap_d = - ceil((double)(dst_p->shared->size) / (double)(src_p->shared->size - dst_p->shared->size)); - olap = (size_t)olap_d; - sp = dp = (uint8_t *)buf; - direction = 1; - } - else { - double olap_d = - ceil((double)(src_p->shared->size) / (double)(dst_p->shared->size - src_p->shared->size)); - olap = (size_t)olap_d; - sp = (uint8_t *)buf + (nelmts - 1) * src_p->shared->size; - dp = (uint8_t *)buf + (nelmts - 1) * dst_p->shared->size; - direction = -1; - } - - /* Allocate enough space for the buffer holding temporary - * converted value - */ - buf_size = ((src.prec > dst.u.f.msize ? src.prec : dst.u.f.msize) + 7) / 8; - int_buf = (uint8_t *)H5MM_calloc(buf_size); - - /* Allocate space for order-reversed source buffer */ - src_rev = (uint8_t *)H5MM_calloc(src_p->shared->size); - - /* The conversion loop */ - for (elmtno = 0; elmtno < nelmts; elmtno++) { - /* Set these variables to default */ - except_ret = H5T_CONV_UNHANDLED; - reverse = true; - - /* Make sure these variables are reset to 0. */ - sign = 0; /*source sign bit value */ - is_max_neg = 0; /*source is maximal negative value*/ - do_round = 0; /*whether there is roundup */ - sfirst = 0; - - /* - * If the source and destination buffers overlap then use a - * temporary buffer for the destination. - */ - if (direction > 0) { - s = sp; - d = elmtno < olap ? dbuf : dp; - } - else { - s = sp; - d = elmtno + olap >= nelmts ? dbuf : dp; - } -#ifndef NDEBUG - /* I don't quite trust the overlap calculations yet */ - if (d == dbuf) { - assert((dp >= sp && dp < sp + src_p->shared->size) || - (sp >= dp && sp < dp + dst_p->shared->size)); - } - else { - assert((dp < sp && dp + dst_p->shared->size <= sp) || - (sp < dp && sp + src_p->shared->size <= dp)); - } -#endif - - /* Put the data in little endian order so our loops aren't so - * complicated. We'll do all the conversion stuff assuming - * little endian and then we'll fix the order at the end. - */ - if (H5T_ORDER_BE == src.order) { - half_size = src_p->shared->size / 2; - for (i = 0; i < half_size; i++) { - tmp1 = s[src_p->shared->size - (i + 1)]; - s[src_p->shared->size - (i + 1)] = s[i]; - s[i] = tmp1; - } - } - - /* Zero-set all destination bits*/ - H5T__bit_set(d, dst.offset, dst.prec, false); - - /* Copy source into a temporary buffer */ - H5T__bit_copy(int_buf, (size_t)0, s, src.offset, src.prec); - - /* Find the sign bit value of the source */ - if (H5T_SGN_2 == src.u.i.sign) - sign = (size_t)H5T__bit_get_d(int_buf, src.prec - 1, (size_t)1); - - /* What is the bit position(starting from 0 as first one) for the most significant - * bit(MSB) of S which is set? - */ - if (H5T_SGN_2 == src.u.i.sign) { - sfirst = H5T__bit_find(int_buf, (size_t)0, src.prec - 1, H5T_BIT_MSB, true); - if (sign && sfirst < 0) - /* The case 0x80...00, which is negative with maximal value */ - is_max_neg = 1; - } - else if (H5T_SGN_NONE == src.u.i.sign) - sfirst = H5T__bit_find(int_buf, (size_t)0, src.prec, H5T_BIT_MSB, true); - - /* Handle special cases here. Integer is zero */ - if (!sign && sfirst < 0) - goto padding; - - /* Convert source integer if it's negative */ - if (H5T_SGN_2 == src.u.i.sign && sign) { - if (!is_max_neg) { - /* Equivalent to ~(i - 1) */ - H5T__bit_dec(int_buf, (size_t)0, buf_size * 8); - H5T__bit_neg(int_buf, (size_t)0, buf_size * 8); - sfirst = H5T__bit_find(int_buf, (size_t)0, src.prec - 1, H5T_BIT_MSB, true); - } - else { - /* If it's maximal negative number 0x80...000, treat it as if it overflowed - * (create a carry) to help conversion. i.e. a character type number 0x80 - * is treated as 0x100. - */ - sfirst = (ssize_t)(src.prec - 1); - is_max_neg = 0; - } - if (sfirst < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "zero bit not found"); - - /* Sign bit has been negated if bit vector isn't 0x80...00. Set all bits in front of - * sign bit to 0 in the temporary buffer because they're all negated from the previous - * step. - */ - H5T__bit_set(int_buf, src.prec, (buf_size * 8) - src.prec, 0); - - /* Set sign bit in destination */ - H5T__bit_set_d(d, dst.u.f.sign, (size_t)1, (hsize_t)sign); - } /* end if */ - - first = (size_t)sfirst; - - /* Calculate the true destination exponent by adjusting according to - * the destination exponent bias. Implied and non-implied normalization - * should be the same. - */ - if (H5T_NORM_NONE == dst.u.f.norm || H5T_NORM_IMPLIED == dst.u.f.norm) { - expo = first + dst.u.f.ebias; - } - else { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "normalization method not implemented yet"); - } - - /* Handle mantissa part here */ - if (H5T_NORM_IMPLIED == dst.u.f.norm) { - /* Imply first bit */ - H5T__bit_set(int_buf, first, (size_t)1, 0); - } - else if (H5T_NORM_NONE == dst.u.f.norm) { - first++; - } - - /* Roundup for mantissa */ - if (first > dst.u.f.msize) { - /* If the bit sequence is bigger than the mantissa part, there'll be some - * precision loss. Let user's handler deal with the case if it's present - */ - if (conv_ctx->u.conv.cb_struct.func) { - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); /*reverse order first*/ - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_PRECISION, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, conv_ctx->u.conv.cb_struct.user_data); - } - - if (except_ret == H5T_CONV_HANDLED) { - reverse = false; - goto padding; - } - else if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); - - /* If user's exception handler does deal with it, we do it by dropping off the - * extra bits at the end and do rounding. If we have .50...0(decimal) after radix - * point, we do roundup when the least significant digit before radix is odd, we do - * rounddown if it's even. - */ - - /* Check 1st dropoff bit, see if it's set. */ - if (H5T__bit_get_d(int_buf, ((first - dst.u.f.msize) - 1), (size_t)1)) { - /* Check all bits after 1st dropoff bit, see if any of them is set. */ - if (((first - dst.u.f.msize) - 1) > 0 && - H5T__bit_get_d(int_buf, (size_t)0, ((first - dst.u.f.msize) - 1))) - do_round = 1; - else { /* The .50...0 case */ - /* Check if the least significant bit is odd. */ - if (H5T__bit_get_d(int_buf, (first - dst.u.f.msize), (size_t)1)) - do_round = 1; - } - } - - /* Right shift to drop off extra bits */ - H5T__bit_shift(int_buf, (ssize_t)(dst.u.f.msize - first), (size_t)0, buf_size * 8); - - if (do_round) { - H5T__bit_inc(int_buf, (size_t)0, buf_size * 8); - do_round = 0; - - /* If integer is like 0x0ff...fff and we need to round up the - * last f, we get 0x100...000. Treat this special case here. - */ - if (H5T__bit_get_d(int_buf, dst.u.f.msize, (size_t)1)) { - if (H5T_NORM_IMPLIED == dst.u.f.norm) { - /* The bit at this 1's position was impled already, so this - * number should be 0x200...000. We need to increment the - * exponent in this case. - */ - expo++; - } - else if (H5T_NORM_NONE == dst.u.f.norm) { - /* Right shift 1 bit to let the carried 1 fit in the mantissa, - * and increment exponent by 1. - */ - H5T__bit_shift(int_buf, (ssize_t)-1, (size_t)0, buf_size * 8); - expo++; - } - } - } - } - else { - /* The bit sequence can fit mantissa part. Left shift to fit in from high-order of - * bit position. */ - H5T__bit_shift(int_buf, (ssize_t)(dst.u.f.msize - first), (size_t)0, dst.u.f.msize); - } - - /* Check if the exponent is too big */ - expo_max = (hsize_t)(pow(2.0, (double)dst.u.f.esize) - 1); - - if (expo > expo_max) { /*overflows*/ - if (conv_ctx->u.conv.cb_struct - .func) { /*user's exception handler. Reverse back source order*/ - H5T__reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); /*reverse order first*/ - except_ret = (conv_ctx->u.conv.cb_struct.func)( - H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, - conv_ctx->u.conv.dst_type_id, src_rev, d, conv_ctx->u.conv.cb_struct.user_data); - - if (except_ret == H5T_CONV_ABORT) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, - "can't handle conversion exception"); - else if (except_ret == H5T_CONV_HANDLED) { - reverse = false; - goto padding; - } - } - - if (!conv_ctx->u.conv.cb_struct.func || (except_ret == H5T_CONV_UNHANDLED)) { - /*make destination infinity by setting exponent to maximal number and - *mantissa to zero.*/ - expo = expo_max; - memset(int_buf, 0, buf_size); - } - } - - if (except_ret == H5T_CONV_UNHANDLED) { - /* Set exponent in destination */ - H5T__bit_set_d(d, dst.u.f.epos, dst.u.f.esize, expo); - - /* Copy mantissa into destination */ - H5T__bit_copy(d, dst.u.f.mpos, int_buf, (size_t)0, - (buf_size * 8) > dst.u.f.msize ? dst.u.f.msize : buf_size * 8); - } - -padding: - /* - * Set padding areas in destination. - */ - if (dst.offset > 0) { - assert(H5T_PAD_ZERO == dst.lsb_pad || H5T_PAD_ONE == dst.lsb_pad); - H5T__bit_set(d, (size_t)0, dst.offset, (bool)(H5T_PAD_ONE == dst.lsb_pad)); - } - if (dst.offset + dst.prec != 8 * dst_p->shared->size) { - assert(H5T_PAD_ZERO == dst.msb_pad || H5T_PAD_ONE == dst.msb_pad); - H5T__bit_set(d, dst.offset + dst.prec, 8 * dst_p->shared->size - (dst.offset + dst.prec), - (bool)(H5T_PAD_ONE == dst.msb_pad)); - } - - /* - * Put the destination in the correct byte order. See note at - * beginning of loop. - */ - if (H5T_ORDER_BE == dst.order && reverse) { - half_size = dst_p->shared->size / 2; - for (i = 0; i < half_size; i++) { - uint8_t tmp = d[dst_p->shared->size - (i + 1)]; - d[dst_p->shared->size - (i + 1)] = d[i]; - d[i] = tmp; - } - } - else if (H5T_ORDER_VAX == dst.order && reverse) { - tsize = dst_p->shared->size; - assert(0 == tsize % 2); - - for (i = 0; i < tsize; i += 4) { - tmp1 = d[i]; - tmp2 = d[i + 1]; - - d[i] = d[(tsize - 2) - i]; - d[i + 1] = d[(tsize - 1) - i]; - - d[(tsize - 2) - i] = tmp1; - d[(tsize - 1) - i] = tmp2; - } - } - - /* - * If we had used a temporary buffer for the destination then we - * should copy the value to the true destination buffer. - */ - if (d == dbuf) - H5MM_memcpy(dp, d, dst_p->shared->size); - if (buf_stride) { - sp += direction * (ssize_t)buf_stride; - dp += direction * (ssize_t)buf_stride; - } - else { - sp += direction * (ssize_t)src_p->shared->size; - dp += direction * (ssize_t)dst_p->shared->size; - } - - memset(int_buf, 0, buf_size); - } - - break; - - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ - -done: - if (int_buf) - H5MM_xfree(int_buf); - if (src_rev) - H5MM_free(src_rev); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__conv_i_f() */ - -/*------------------------------------------------------------------------- - * Function: H5T__reverse_order - * - * Purpose: Internal assisting function to reverse the order of - * a sequence of byte when it's big endian or VAX order. - * The byte sequence simulates the endian order. - * - * Return: Success: A pointer to the reversed byte sequence - * - * Failure: Null - * - *------------------------------------------------------------------------- - */ -static herr_t -H5T__reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order) -{ - size_t i; - - FUNC_ENTER_PACKAGE_NOERR - - assert(s); - assert(size); - - if (H5T_ORDER_VAX == order) { - for (i = 0; i < size; i += 2) { - rev[i] = s[(size - 2) - i]; - rev[i + 1] = s[(size - 1) - i]; - } - } - else if (H5T_ORDER_BE == order) { - for (i = 0; i < size; i++) - rev[size - (i + 1)] = s[i]; - } - else { - for (i = 0; i < size; i++) - rev[i] = s[i]; - } - - FUNC_LEAVE_NOAPI(SUCCEED) -} - -/*------------------------------------------------------------------------- - * Function: H5T_reclaim - * - * Purpose: Frees the buffers allocated for storing variable-length data - * in memory. Only frees the VL data in the selection defined in the - * dataspace. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_reclaim(const H5T_t *type, H5S_t *space, void *buf) -{ - H5S_sel_iter_op_t dset_op; /* Operator for iteration */ - H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ - herr_t ret_value = FAIL; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Check args */ - assert(type); - assert(space); - assert(buf); - - /* Get the allocation info */ - if (H5CX_get_vlen_alloc_info(&vl_alloc_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info"); - - /* Call H5S_select_iterate with args, etc. */ - dset_op.op_type = H5S_SEL_ITER_OP_LIB; - dset_op.u.lib_op = H5T_reclaim_cb; - - ret_value = H5S_select_iterate(buf, type, space, &dset_op, &vl_alloc_info); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_reclaim() */ - -/*------------------------------------------------------------------------- - * Function: H5T_reclaim_cb - * - * Purpose: Iteration callback to reclaim conversion allocated memory for a - * buffer element. - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned H5_ATTR_UNUSED ndim, const hsize_t H5_ATTR_UNUSED *point, - void *op_data) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Sanity check */ - assert(elem); - assert(dt); - - if (dt->shared->type == H5T_REFERENCE) { - if (H5T__ref_reclaim(elem, dt) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim ref elements"); - } - else { - assert(op_data); - - /* Allow vlen reclaim to recurse into that routine */ - if (H5T__vlen_reclaim(elem, dt, (H5T_vlen_alloc_info_t *)op_data) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim vlen elements"); - } - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_reclaim_cb() */ diff --git a/src/H5Tconv.h b/src/H5Tconv.h new file mode 100644 index 00000000000..4dae848269d --- /dev/null +++ b/src/H5Tconv.h @@ -0,0 +1,195 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_H +#define H5Tconv_H + +/* Private headers needed by this file */ +#include "H5private.h" +#include "H5Sprivate.h" +#include "H5Tprivate.h" + +/**************************/ +/* Library Private Macros */ +/**************************/ + +/* Length of debugging name buffer */ +#define H5T_NAMELEN 32 + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + +/* Forward reference of H5S_t */ +struct H5S_t; + +/* Structure for conversion callback property */ +typedef struct H5T_conv_cb_t { + H5T_conv_except_func_t func; + void *user_data; +} H5T_conv_cb_t; + +/* Context struct for information used during datatype conversions. + * Which union member is valid to read from is dictated by the + * accompanying H5T_cdata_t structure's H5T_cmd_t member value. + */ +typedef struct H5T_conv_ctx_t { + union { + /* + * Fields only valid during conversion function initialization + * (H5T_cmd_t H5T_CONV_INIT) + */ + struct H5T_conv_ctx_init_fields { + H5T_conv_cb_t cb_struct; + } init; + + /* + * Fields only valid during conversion function conversion + * process (H5T_cmd_t H5T_CONV_CONV) + */ + struct H5T_conv_ctx_conv_fields { + H5T_conv_cb_t cb_struct; + hid_t dxpl_id; + hid_t src_type_id; + hid_t dst_type_id; + + /* Is conversion currently being done on a member of + * a container type, like a compound datatype? If so, + * cached information can be reused rather than creating + * and tearing it down for every compound element. + */ + bool recursive; + } conv; + + /* + * Fields only valid during conversion function free process + * (H5T_cmd_t H5T_CONV_FREE) + */ + struct H5T_conv_ctx_free_fields { + hid_t src_type_id; + hid_t dst_type_id; + } free; + } u; +} H5T_conv_ctx_t; + +/* Library internal datatype conversion functions are... */ +typedef herr_t (*H5T_lib_conv_t)(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion callbacks */ +typedef struct H5T_conv_func_t { + bool is_app; /* Whether conversion function is registered from application */ + union { + H5T_conv_t app_func; /* Application data conversion function */ + H5T_lib_conv_t lib_func; /* Library internal data conversion function */ + } u; +} H5T_conv_func_t; + +#ifdef H5T_DEBUG +/* Statistics about a conversion function */ +typedef struct H5T_stats_t { + unsigned ncalls; /*num calls to conversion function */ + hsize_t nelmts; /*total data points converted */ + H5_timevals_t times; /*total time for conversion */ +} H5T_stats_t; +#endif + +/* The datatype conversion database */ +typedef struct H5T_path_t { + char name[H5T_NAMELEN]; /*name for debugging only */ + H5T_t *src; /*source datatype */ + H5T_t *dst; /*destination datatype */ + H5T_conv_func_t conv; /* Conversion function */ + bool is_hard; /*is it a hard function? */ + bool is_noop; /*is it the noop conversion? */ + H5T_cdata_t cdata; /*data for this function */ + +#ifdef H5T_DEBUG + H5T_stats_t stats; /*statistics for the conversion */ +#endif +} H5T_path_t; + +/* The master list of soft conversion functions */ +typedef struct H5T_soft_t { + char name[H5T_NAMELEN]; /*name for debugging only */ + H5T_class_t src; /*source datatype class */ + H5T_class_t dst; /*destination datatype class */ + H5T_conv_func_t conv; /*the conversion function */ +} H5T_soft_t; + +/* Values for the optimization of compound data reading and writing. They indicate + * whether the fields of the source and destination are subset of each other and + * there is no conversion needed. + */ +typedef enum { + H5T_SUBSET_BADVALUE = -1, /* Invalid value */ + H5T_SUBSET_FALSE = 0, /* Source and destination aren't subset of each other */ + H5T_SUBSET_SRC, /* Source is the subset of dest and no conversion is needed */ + H5T_SUBSET_DST, /* Dest is the subset of source and no conversion is needed */ + H5T_SUBSET_CAP /* Must be the last value */ +} H5T_subset_t; + +typedef struct H5T_subset_info_t { + H5T_subset_t subset; /* See above */ + size_t copy_size; /* Size in bytes, to copy for each element */ +} H5T_subset_info_t; + +/*****************************/ +/* Library-private Variables */ +/*****************************/ + +/***************************************/ +/* Library-private Function Prototypes */ +/***************************************/ + +H5_DLL herr_t H5T_convert(H5T_path_t *tpath, const H5T_t *src_type, const H5T_t *dst_type, size_t nelmts, + size_t buf_stride, size_t bkg_stride, void *buf, void *bkg); + +/* Helper function for H5T_convert that accepts a pointer to a H5T_conv_ctx_t structure */ +H5_DLL herr_t H5T_convert_with_ctx(H5T_path_t *tpath, const H5T_t *src_type, const H5T_t *dst_type, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion path and path table routines */ +H5_DLL H5T_path_t *H5T_path_find(const H5T_t *src, const H5T_t *dst); +H5_DLL bool H5T_path_noop(const H5T_path_t *p); +H5_DLL bool H5T_noop_conv(const H5T_t *src, const H5T_t *dst); +H5_DLL H5T_bkg_t H5T_path_bkg(const H5T_path_t *p); +H5_DLL H5T_subset_info_t *H5T_path_compound_subset(const H5T_path_t *p); + +/* Generic routines */ +H5_DLL herr_t H5T_reclaim(const H5T_t *type, struct H5S_t *space, void *buf); +H5_DLL herr_t H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned ndim, const hsize_t *point, void *op_data); +H5_DLL bool H5T_get_force_conv(const H5T_t *dt); + +/* Conversion functions */ +H5_DLL herr_t H5T__conv_noop(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); +H5_DLL herr_t H5T__conv_order(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); +H5_DLL herr_t H5T__conv_order_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); + +/* Utility functions */ +H5_DLL herr_t H5T__reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order); + +/* Debugging functions */ +H5_DLL herr_t H5T__print_path_stats(H5T_path_t *path, int *nprint /*in,out*/); + +/* Testing functions */ +H5_DLL int H5T__get_path_table_npaths(void); + +#endif /* H5Tconv_H */ diff --git a/src/H5Tconv_array.c b/src/H5Tconv_array.c new file mode 100644 index 00000000000..e192c7267e0 --- /dev/null +++ b/src/H5Tconv_array.c @@ -0,0 +1,234 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Datatype conversion functions for array datatypes + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5Eprivate.h" +#include "H5Iprivate.h" +#include "H5Tconv.h" +#include "H5Tconv_array.h" + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Private conversion data for array datatypes */ +typedef struct H5T_conv_array_t { + H5T_path_t *tpath; /* Conversion path for parent types */ +} H5T_conv_array_t; + +/*------------------------------------------------------------------------- + * Function: H5T__conv_array + * + * Purpose: Converts between array datatypes in memory and on disk. + * This is a soft conversion function. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_array(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *_bkg) +{ + H5T_conv_array_t *priv = NULL; /* Private conversion data */ + H5T_conv_ctx_t tmp_conv_ctx = {0}; /* Temporary conversion context */ + H5T_t *tsrc_cpy = NULL; /* Temporary copy of source base datatype */ + H5T_t *tdst_cpy = NULL; /* Temporary copy of destination base datatype */ + hid_t tsrc_id = H5I_INVALID_HID; /* Temporary type atom */ + hid_t tdst_id = H5I_INVALID_HID; /* Temporary type atom */ + uint8_t *sp, *dp, *bp; /* Source, dest, and bkg traversal ptrs */ + ssize_t src_delta, dst_delta, bkg_delta; /* Source, dest, and bkg strides */ + int direction; /* Direction of traversal */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* + * First, determine if this conversion function applies to the + * conversion path SRC-->DST. If not, return failure; + * otherwise initialize the `priv' field of `cdata' with + * information that remains (almost) constant for this + * conversion path. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + assert(H5T_ARRAY == src->shared->type); + assert(H5T_ARRAY == dst->shared->type); + + /* Check the number and sizes of the dimensions */ + if (src->shared->u.array.ndims != dst->shared->u.array.ndims) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "array datatypes do not have the same number of dimensions"); + for (unsigned u = 0; u < src->shared->u.array.ndims; u++) + if (src->shared->u.array.dim[u] != dst->shared->u.array.dim[u]) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "array datatypes do not have the same sizes of dimensions"); + + /* Initialize parent type conversion if necessary. We need to do this here because we need to + * report whether we need a background buffer or not. */ + if (!cdata->priv) { + /* Allocate private data */ + if (NULL == (priv = (H5T_conv_array_t *)(cdata->priv = calloc(1, sizeof(*priv))))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + + /* Find conversion path between parent types */ + if (NULL == (priv->tpath = H5T_path_find(src->shared->parent, dst->shared->parent))) { + free(priv); + cdata->priv = NULL; + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unable to convert between src and dest datatype"); + } + + /* Array datatypes don't need a background buffer by themselves, but the parent type might. + * Pass the need_bkg field through to the upper layer. */ + cdata->need_bkg = priv->tpath->cdata.need_bkg; + } + + break; + + case H5T_CONV_FREE: + /* + * Free private data + */ + free(cdata->priv); + cdata->priv = NULL; + + break; + + case H5T_CONV_CONV: + /* + * Conversion. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + priv = (H5T_conv_array_t *)cdata->priv; + + /* Initialize temporary conversion context */ + tmp_conv_ctx = *conv_ctx; + + /* + * Do we process the values from beginning to end or vice + * versa? Also, how many of the elements have the source and + * destination areas overlapping? + */ + if (src->shared->size >= dst->shared->size || buf_stride > 0) { + sp = dp = (uint8_t *)_buf; + bp = _bkg; + direction = 1; + } + else { + sp = (uint8_t *)_buf + (nelmts - 1) * (buf_stride ? buf_stride : src->shared->size); + dp = (uint8_t *)_buf + (nelmts - 1) * (buf_stride ? buf_stride : dst->shared->size); + bp = _bkg ? (uint8_t *)_bkg + (nelmts - 1) * (bkg_stride ? bkg_stride : dst->shared->size) + : NULL; + direction = -1; + } + + /* + * Direction & size of buffer traversal. + */ + H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); + H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); + H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); + src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src->shared->size); + dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst->shared->size); + bkg_delta = (ssize_t)direction * (ssize_t)(bkg_stride ? bkg_stride : dst->shared->size); + + /* Set up conversion path for base elements */ + if (!H5T_path_noop(priv->tpath)) { + if (NULL == (tsrc_cpy = H5T_copy(src->shared->parent, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, + "unable to copy src base type for conversion"); + + if (NULL == (tdst_cpy = H5T_copy(dst->shared->parent, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, + "unable to copy dst base type for conversion"); + + /* Create IDs for the array base datatypes if the conversion path uses an + * application conversion function or if a conversion exception function + * was provided. + */ + if (priv->tpath->conv.is_app || conv_ctx->u.conv.cb_struct.func) { + if ((tsrc_id = H5I_register(H5I_DATATYPE, tsrc_cpy, false)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "unable to register ID for source base datatype"); + if ((tdst_id = H5I_register(H5I_DATATYPE, tdst_cpy, false)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "unable to register ID for destination base datatype"); + } + + /* Update IDs in conversion context */ + tmp_conv_ctx.u.conv.src_type_id = tsrc_id; + tmp_conv_ctx.u.conv.dst_type_id = tdst_id; + } + + /* Perform the actual conversion */ + tmp_conv_ctx.u.conv.recursive = true; + for (size_t elmtno = 0; elmtno < nelmts; elmtno++) { + /* Copy the source array into the correct location for the destination */ + memmove(dp, sp, src->shared->size); + + /* Convert array */ + if (H5T_convert_with_ctx(priv->tpath, tsrc_cpy, tdst_cpy, &tmp_conv_ctx, + src->shared->u.array.nelem, (size_t)0, (size_t)0, dp, bp) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "datatype conversion failed"); + + /* Advance the source, destination, and background pointers */ + sp += src_delta; + dp += dst_delta; + if (bp) + bp += bkg_delta; + } /* end for */ + tmp_conv_ctx.u.conv.recursive = false; + + break; + + default: /* Some other command we don't know about yet.*/ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + if (tsrc_id >= 0) { + if (H5I_dec_ref(tsrc_id) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); + } + else if (tsrc_cpy) { + if (H5T_close(tsrc_cpy) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); + } + if (tdst_id >= 0) { + if (H5I_dec_ref(tdst_id) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); + } + else if (tdst_cpy) { + if (H5T_close(tdst_cpy) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_array() */ diff --git a/src/H5Tconv_array.h b/src/H5Tconv_array.h new file mode 100644 index 00000000000..be1ba8ff5f1 --- /dev/null +++ b/src/H5Tconv_array.h @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_array_H +#define H5Tconv_array_H + +/* Private headers needed by this file */ +#include "H5Tpkg.h" + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/****************************************/ +/* Soft (emulated) conversion functions */ +/****************************************/ + +/* Conversion functions between array datatypes */ +H5_DLL herr_t H5T__conv_array(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/*********************************************/ +/* Hard (compiler cast) conversion functions */ +/*********************************************/ + +#endif /* H5Tconv_array_H */ diff --git a/src/H5Tconv_bitfield.c b/src/H5Tconv_bitfield.c new file mode 100644 index 00000000000..486036ad260 --- /dev/null +++ b/src/H5Tconv_bitfield.c @@ -0,0 +1,268 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Datatype conversion functions for bitfield datatypes + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5Eprivate.h" +#include "H5Tconv.h" +#include "H5Tconv_bitfield.h" + +/*------------------------------------------------------------------------- + * Function: H5T__conv_b_b + * + * Purpose: Convert from one bitfield to any other bitfield. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_b_b(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *_buf, + void H5_ATTR_UNUSED *background) +{ + uint8_t *buf = (uint8_t *)_buf; + ssize_t direction; /*direction of traversal */ + size_t elmtno; /*element number */ + size_t olap; /*num overlapping elements */ + size_t half_size; /*1/2 of total size for swapping*/ + uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ + uint8_t dbuf[256] = {0}; /*temp destination buffer */ + size_t msb_pad_offset; /*offset for dest MSB padding */ + size_t i; + uint8_t *src_rev = NULL; /*order-reversed source buffer */ + H5T_conv_ret_t except_ret; /*return of callback function */ + bool reverse; /*if reverse the order of destination */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* Capability query */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); + if (H5T_ORDER_LE != dst->shared->u.atomic.order && H5T_ORDER_BE != dst->shared->u.atomic.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + + /* + * Do we process the values from beginning to end or vice versa? Also, + * how many of the elements have the source and destination areas + * overlapping? + */ + if (src->shared->size == dst->shared->size || buf_stride) { + sp = dp = (uint8_t *)buf; + direction = 1; + olap = nelmts; + } + else if (src->shared->size >= dst->shared->size) { + double olap_d = + ceil((double)(dst->shared->size) / (double)(src->shared->size - dst->shared->size)); + + olap = (size_t)olap_d; + sp = dp = (uint8_t *)buf; + direction = 1; + } + else { + double olap_d = + ceil((double)(src->shared->size) / (double)(dst->shared->size - src->shared->size)); + olap = (size_t)olap_d; + sp = (uint8_t *)buf + (nelmts - 1) * src->shared->size; + dp = (uint8_t *)buf + (nelmts - 1) * dst->shared->size; + direction = -1; + } + + /* Allocate space for order-reversed source buffer */ + src_rev = (uint8_t *)H5MM_calloc(src->shared->size); + + /* The conversion loop */ + H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); + H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); + H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); + for (elmtno = 0; elmtno < nelmts; elmtno++) { + + /* + * If the source and destination buffers overlap then use a + * temporary buffer for the destination. + */ + if (direction > 0) { + s = sp; + d = elmtno < olap ? dbuf : dp; + } /* end if */ + else { + s = sp; + d = (elmtno + olap) >= nelmts ? dbuf : dp; + } /* end else */ +#ifndef NDEBUG + /* I don't quite trust the overlap calculations yet */ + if (d == dbuf) + assert((dp >= sp && dp < sp + src->shared->size) || + (sp >= dp && sp < dp + dst->shared->size)); + else + assert((dp < sp && dp + dst->shared->size <= sp) || + (sp < dp && sp + src->shared->size <= dp)); +#endif + + /* + * Put the data in little endian order so our loops aren't so + * complicated. We'll do all the conversion stuff assuming + * little endian and then we'll fix the order at the end. + */ + if (H5T_ORDER_BE == src->shared->u.atomic.order) { + half_size = src->shared->size / 2; + for (i = 0; i < half_size; i++) { + uint8_t tmp = s[src->shared->size - (i + 1)]; + s[src->shared->size - (i + 1)] = s[i]; + s[i] = tmp; + } /* end for */ + } /* end if */ + + /* Initiate these variables */ + except_ret = H5T_CONV_UNHANDLED; + reverse = true; + + /* + * Copy the significant part of the value. If the source is larger + * than the destination then invoke the overflow function or copy + * as many bits as possible. Zero extra bits in the destination. + */ + if (src->shared->u.atomic.prec > dst->shared->u.atomic.prec) { + /*overflow*/ + if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, conv_ctx->u.conv.cb_struct.user_data); + } /* end if */ + + if (except_ret == H5T_CONV_UNHANDLED) { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + dst->shared->u.atomic.prec); + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) + /*Don't reverse because user handles it*/ + reverse = false; + } + else { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + src->shared->u.atomic.prec); + H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, + dst->shared->u.atomic.prec - src->shared->u.atomic.prec, false); + } + + /* + * Fill the destination padding areas. + */ + switch (dst->shared->u.atomic.lsb_pad) { + case H5T_PAD_ZERO: + H5T__bit_set(d, (size_t)0, dst->shared->u.atomic.offset, false); + break; + + case H5T_PAD_ONE: + H5T__bit_set(d, (size_t)0, dst->shared->u.atomic.offset, true); + break; + + case H5T_PAD_ERROR: + case H5T_PAD_BACKGROUND: + case H5T_NPAD: + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported LSB padding"); + } /* end switch */ + msb_pad_offset = dst->shared->u.atomic.offset + dst->shared->u.atomic.prec; + switch (dst->shared->u.atomic.msb_pad) { + case H5T_PAD_ZERO: + H5T__bit_set(d, msb_pad_offset, 8 * dst->shared->size - msb_pad_offset, false); + break; + + case H5T_PAD_ONE: + H5T__bit_set(d, msb_pad_offset, 8 * dst->shared->size - msb_pad_offset, true); + break; + + case H5T_PAD_ERROR: + case H5T_PAD_BACKGROUND: + case H5T_NPAD: + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported MSB padding"); + } /* end switch */ + + /* + * Put the destination in the correct byte order. See note at + * beginning of loop. + */ + if (H5T_ORDER_BE == dst->shared->u.atomic.order && reverse) { + half_size = dst->shared->size / 2; + for (i = 0; i < half_size; i++) { + uint8_t tmp = d[dst->shared->size - (i + 1)]; + d[dst->shared->size - (i + 1)] = d[i]; + d[i] = tmp; + } /* end for */ + } /* end if */ + + /* + * If we had used a temporary buffer for the destination then we + * should copy the value to the true destination buffer. + */ + if (d == dbuf) + H5MM_memcpy(dp, d, dst->shared->size); + if (buf_stride) { + sp += direction * + (ssize_t)buf_stride; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ + dp += direction * + (ssize_t)buf_stride; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ + } /* end if */ + else { + sp += direction * + (ssize_t) + src->shared->size; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ + dp += direction * + (ssize_t) + dst->shared->size; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ + } /* end else */ + } /* end for */ + + break; + + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + if (src_rev) + H5MM_free(src_rev); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_b_b() */ diff --git a/src/H5Tconv_bitfield.h b/src/H5Tconv_bitfield.h new file mode 100644 index 00000000000..aece3c38a12 --- /dev/null +++ b/src/H5Tconv_bitfield.h @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_bitfield_H +#define H5Tconv_bitfield_H + +/* Private headers needed by this file */ +#include "H5Tpkg.h" + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/****************************************/ +/* Soft (emulated) conversion functions */ +/****************************************/ + +/* Conversion functions between bitfield datatypes */ +H5_DLL herr_t H5T__conv_b_b(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); + +/*********************************************/ +/* Hard (compiler cast) conversion functions */ +/*********************************************/ + +#endif /* H5Tconv_bitfield_H */ diff --git a/src/H5Tconv_compound.c b/src/H5Tconv_compound.c new file mode 100644 index 00000000000..3e988b33f18 --- /dev/null +++ b/src/H5Tconv_compound.c @@ -0,0 +1,926 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Datatype conversion functions for compound datatypes + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5Eprivate.h" +#include "H5Iprivate.h" +#include "H5Tconv.h" +#include "H5Tconv_compound.h" + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Private conversion data for compound datatypes */ +typedef struct H5T_conv_struct_t { + int *src2dst; /* mapping from src to dst member num */ + H5T_t **src_memb; /* source member datatypes */ + H5T_t **dst_memb; /* destination member datatypes */ + hid_t *src_memb_id; /* source member type ID's */ + hid_t *dst_memb_id; /* destination member type ID's */ + H5T_path_t **memb_path; /* conversion path for each member */ + H5T_subset_info_t subset_info; /* info related to compound subsets */ + unsigned src_nmembs; /* needed by free function */ +} H5T_conv_struct_t; + +/********************/ +/* Local Prototypes */ +/********************/ + +static herr_t H5T__conv_struct_init(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx); +static herr_t H5T__conv_struct_free(H5T_conv_struct_t *priv); + +/*------------------------------------------------------------------------- + * Function: H5T__conv_struct_subset + * + * Purpose: A quick way to return a field in a struct private in this + * file. The `subset` enum field of the `H5T_subset_info_t` + * structure indicates whether the source members are a subset + * of the destination or the destination members are a subset + * of the source, and the order is the same, and no conversion + * is needed. For example: + * + * struct source { struct destination { + * TYPE1 A; --> TYPE1 A; + * TYPE2 B; --> TYPE2 B; + * TYPE3 C; --> TYPE3 C; + * }; TYPE4 D; + * TYPE5 E; + * }; + * + * Return: A pointer to the subset info struct in `cdata`. Points + * directly into the structure. + * + *------------------------------------------------------------------------- + */ +H5T_subset_info_t * +H5T__conv_struct_subset(const H5T_cdata_t *cdata) +{ + H5T_conv_struct_t *priv = NULL; + + FUNC_ENTER_PACKAGE_NOERR + + assert(cdata); + assert(cdata->priv); + + priv = (H5T_conv_struct_t *)(cdata->priv); + + FUNC_LEAVE_NOAPI((H5T_subset_info_t *)&priv->subset_info) +} /* end H5T__conv_struct_subset() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_struct_init + * + * Purpose: Initialize the `priv' field of `cdata' with conversion + * information that is relatively constant. If `priv' is + * already initialized then the member conversion functions + * are recalculated. + * + * Priv fields are indexed by source member number or + * destination member number depending on whether the field + * contains information about the source datatype or the + * destination datatype (fields that contains the same + * information for both source and destination are indexed by + * source member number). The src2dst[] priv array maps + * source member numbers to destination member numbers, but + * if the source member doesn't have a corresponding + * destination member then the src2dst[i] == -1. + * + * Special optimization case when the source and destination + * members are a subset of each other, and the order is the + * same, and no conversion is needed. For example: + * + * struct source { struct destination { + * TYPE1 A; --> TYPE1 A; + * TYPE2 B; --> TYPE2 B; + * TYPE3 C; --> TYPE3 C; + * }; TYPE4 D; + * TYPE5 E; + * }; + * + * or + * + * struct destination { struct source { + * TYPE1 A; <-- TYPE1 A; + * TYPE2 B; <-- TYPE2 B; + * TYPE3 C; <-- TYPE3 C; + * }; TYPE4 D; + * TYPE5 E; + * }; + * + * The optimization is simply moving data to the appropriate + * places in the buffer. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__conv_struct_init(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx) +{ + H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv); + int *src2dst = NULL; + unsigned src_nmembs, dst_nmembs; + unsigned i, j; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + src_nmembs = src->shared->u.compnd.nmembs; + dst_nmembs = dst->shared->u.compnd.nmembs; + + if (!priv) { + /* + * Allocate private data structure and arrays. + */ + if (NULL == (priv = (H5T_conv_struct_t *)(cdata->priv = H5MM_calloc(sizeof(H5T_conv_struct_t))))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't allocate private conversion data"); + if (NULL == (priv->src2dst = (int *)H5MM_malloc(src_nmembs * sizeof(int)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "couldn't allocate source to destination member mapping array"); + if (NULL == (priv->src_memb = (H5T_t **)H5MM_malloc(src_nmembs * sizeof(H5T_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "couldn't allocate source compound member datatype array"); + if (NULL == (priv->dst_memb = (H5T_t **)H5MM_malloc(dst_nmembs * sizeof(H5T_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "couldn't allocate destination compound member datatype array"); + + /* Allocate and initialize arrays for datatype IDs */ + if (NULL == (priv->src_memb_id = (hid_t *)H5MM_malloc(src_nmembs * sizeof(hid_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "couldn't allocate source compound member datatype ID array"); + for (i = 0; i < src_nmembs; i++) + priv->src_memb_id[i] = H5I_INVALID_HID; + + if (NULL == (priv->dst_memb_id = (hid_t *)H5MM_malloc(dst_nmembs * sizeof(hid_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "couldn't allocate destination compound member datatype ID array"); + for (i = 0; i < dst_nmembs; i++) + priv->dst_memb_id[i] = H5I_INVALID_HID; + + src2dst = priv->src2dst; + priv->src_nmembs = src_nmembs; + + /* The flag of special optimization to indicate if source members and destination + * members are a subset of each other. Initialize it to false */ + priv->subset_info.subset = H5T_SUBSET_FALSE; + priv->subset_info.copy_size = 0; + + /* + * Ensure that members are sorted. + */ + H5T__sort_value(src, NULL); + H5T__sort_value(dst, NULL); + + /* + * Build a mapping from source member number to destination member + * number. If some source member is not a destination member then that + * mapping element will be negative. Also create atoms for each + * source and destination member datatype if necessary. + */ + for (i = 0; i < src_nmembs; i++) { + src2dst[i] = -1; + for (j = 0; j < dst_nmembs; j++) { + if (!strcmp(src->shared->u.compnd.memb[i].name, dst->shared->u.compnd.memb[j].name)) { + H5_CHECKED_ASSIGN(src2dst[i], int, j, unsigned); + break; + } /* end if */ + } /* end for */ + if (src2dst[i] >= 0) { + H5T_t *type; + + if (NULL == (type = H5T_copy(src->shared->u.compnd.memb[i].type, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, + "can't copy source compound member datatype"); + priv->src_memb[i] = type; + + if (NULL == (type = H5T_copy(dst->shared->u.compnd.memb[src2dst[i]].type, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, + "can't copy destination compound member datatype"); + priv->dst_memb[src2dst[i]] = type; + } /* end if */ + } /* end for */ + } /* end if */ + else { + /* Restore sorted conditions for the datatypes */ + /* (Required for the src2dst array to be valid) */ + H5T__sort_value(src, NULL); + H5T__sort_value(dst, NULL); + } /* end else */ + + /* + * (Re)build the cache of member conversion functions and pointers to + * their cdata entries. + */ + src2dst = priv->src2dst; + H5MM_xfree(priv->memb_path); + if (NULL == + (priv->memb_path = (H5T_path_t **)H5MM_malloc(src->shared->u.compnd.nmembs * sizeof(H5T_path_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + + for (i = 0; i < src_nmembs; i++) { + if (src2dst[i] >= 0) { + H5T_path_t *tpath; + bool need_ids; + + tpath = H5T_path_find(src->shared->u.compnd.memb[i].type, + dst->shared->u.compnd.memb[src2dst[i]].type); + + if (NULL == (priv->memb_path[i] = tpath)) { + H5T__conv_struct_free(priv); + cdata->priv = NULL; + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member datatype"); + } /* end if */ + + /* Create IDs for the compound member datatypes if the conversion path uses + * an application conversion function or if a conversion exception function + * was provided. + */ + need_ids = tpath->conv.is_app || + (cdata->command == H5T_CONV_INIT && conv_ctx->u.init.cb_struct.func) || + (cdata->command == H5T_CONV_CONV && conv_ctx->u.conv.cb_struct.func); + + if (need_ids) { + hid_t tid; + + if ((tid = H5I_register(H5I_DATATYPE, priv->src_memb[i], false)) < 0) { + H5T__conv_struct_free(priv); + cdata->priv = NULL; + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "can't register ID for source compound member datatype"); + } + priv->src_memb_id[i] = tid; + + if ((tid = H5I_register(H5I_DATATYPE, priv->dst_memb[src2dst[i]], false)) < 0) { + H5T__conv_struct_free(priv); + cdata->priv = NULL; + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "can't register ID for destination compound member datatype"); + } + priv->dst_memb_id[src2dst[i]] = tid; + } + } /* end if */ + } /* end for */ + + /* The compound conversion functions need a background buffer */ + cdata->need_bkg = H5T_BKG_YES; + + if (src_nmembs < dst_nmembs) { + priv->subset_info.subset = H5T_SUBSET_SRC; + for (i = 0; i < src_nmembs; i++) { + /* If any of source members doesn't have counterpart in the same + * order or there's conversion between members, don't do the + * optimization. + */ + if (src2dst[i] != (int)i || + (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || + (priv->memb_path[i])->is_noop == false) { + priv->subset_info.subset = H5T_SUBSET_FALSE; + break; + } /* end if */ + } /* end for */ + /* Compute the size of the data to be copied for each element. It + * may be smaller than either src or dst if there is extra space at + * the end of src. + */ + if (priv->subset_info.subset == H5T_SUBSET_SRC) + priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs - 1].offset + + src->shared->u.compnd.memb[src_nmembs - 1].size; + } + else if (dst_nmembs < src_nmembs) { + priv->subset_info.subset = H5T_SUBSET_DST; + for (i = 0; i < dst_nmembs; i++) { + /* If any of source members doesn't have counterpart in the same order or + * there's conversion between members, don't do the optimization. */ + if (src2dst[i] != (int)i || + (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || + (priv->memb_path[i])->is_noop == false) { + priv->subset_info.subset = H5T_SUBSET_FALSE; + break; + } + } /* end for */ + /* Compute the size of the data to be copied for each element. It + * may be smaller than either src or dst if there is extra space at + * the end of dst. + */ + if (priv->subset_info.subset == H5T_SUBSET_DST) + priv->subset_info.copy_size = dst->shared->u.compnd.memb[dst_nmembs - 1].offset + + dst->shared->u.compnd.memb[dst_nmembs - 1].size; + } + else /* If the numbers of source and dest members are equal and no conversion is needed, + * the case should have been handled as noop earlier in H5Dio.c. */ + { + } + + cdata->recalc = false; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_struct_init() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_struct_free + * + * Purpose: Free the private data structure used by the compound + * conversion functions. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__conv_struct_free(H5T_conv_struct_t *priv) +{ + int *src2dst = priv->src2dst; + H5T_t **src_memb = priv->src_memb; + H5T_t **dst_memb = priv->dst_memb; + hid_t *src_memb_id = priv->src_memb_id; + hid_t *dst_memb_id = priv->dst_memb_id; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE_NOERR + + for (unsigned i = 0; i < priv->src_nmembs; i++) + if (src2dst[i] >= 0) { + if (src_memb_id[i] >= 0) { + if (H5I_dec_ref(src_memb_id[i]) < 0) + ret_value = FAIL; /* set return value, but keep going */ + src_memb_id[i] = H5I_INVALID_HID; + src_memb[i] = NULL; + } + else { + if (H5T_close(src_memb[i]) < 0) + ret_value = FAIL; /* set return value, but keep going */ + src_memb[i] = NULL; + } + if (dst_memb_id[src2dst[i]] >= 0) { + if (H5I_dec_ref(dst_memb_id[src2dst[i]]) < 0) + ret_value = FAIL; /* set return value, but keep going */ + dst_memb_id[src2dst[i]] = H5I_INVALID_HID; + dst_memb[src2dst[i]] = NULL; + } + else { + if (H5T_close(dst_memb[src2dst[i]]) < 0) + ret_value = FAIL; /* set return value, but keep going */ + dst_memb[src2dst[i]] = NULL; + } + } /* end if */ + + H5MM_xfree(src2dst); + H5MM_xfree(src_memb); + H5MM_xfree(dst_memb); + H5MM_xfree(src_memb_id); + H5MM_xfree(dst_memb_id); + + H5MM_xfree(priv->memb_path); + H5MM_xfree(priv); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_struct_free() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_struct + * + * Purpose: Converts between compound datatypes. This is a soft + * conversion function. The algorithm is basically: + * + * For each element do + * For I=1..NELMTS do + * If sizeof destination type <= sizeof source type then + * Convert member to destination type; + * Move member as far left as possible; + * + * For I=NELMTS..1 do + * If not destination type then + * Convert member to destination type; + * Move member to correct position in BKG + * + * Copy BKG to BUF + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_struct(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf, void *_bkg) +{ + uint8_t *buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ + uint8_t *bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ + uint8_t *xbuf = buf, *xbkg = bkg; /*temp pointers into buf and bkg*/ + int *src2dst = NULL; /*maps src member to dst member */ + H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/ + H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */ + size_t offset; /*byte offset wrt struct */ + ssize_t src_delta; /*source stride */ + ssize_t bkg_delta; /*background stride */ + size_t elmtno; + unsigned u; /*counters */ + H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv); + H5T_conv_ctx_t tmp_conv_ctx = {0}; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* + * First, determine if this conversion function applies to the + * conversion path SRC-->DST. If not, return failure; + * otherwise initialize the `priv' field of `cdata' with information + * that remains (almost) constant for this conversion path. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); + if (H5T_COMPOUND != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype"); + if (H5T_COMPOUND != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype"); + + if (H5T__conv_struct_init(src, dst, cdata, conv_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); + break; + + case H5T_CONV_FREE: { + /* + * Free the private conversion data. + */ + herr_t status = H5T__conv_struct_free(priv); + cdata->priv = NULL; + if (status < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free private conversion data"); + + break; + } + + case H5T_CONV_CONV: + /* + * Conversion. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + assert(priv); + assert(bkg && cdata->need_bkg); + + /* Initialize temporary conversion context */ + tmp_conv_ctx = *conv_ctx; + + if (cdata->recalc && H5T__conv_struct_init(src, dst, cdata, conv_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); + + /* + * Insure that members are sorted. + */ + H5T__sort_value(src, NULL); + H5T__sort_value(dst, NULL); + src2dst = priv->src2dst; + + /* + * Direction of conversion and striding through background. + */ + if (buf_stride) { + H5_CHECKED_ASSIGN(src_delta, ssize_t, buf_stride, size_t); + if (!bkg_stride) { + H5_CHECKED_ASSIGN(bkg_delta, ssize_t, dst->shared->size, size_t); + } /* end if */ + else + H5_CHECKED_ASSIGN(bkg_delta, ssize_t, bkg_stride, size_t); + } /* end if */ + else if (dst->shared->size <= src->shared->size) { + H5_CHECKED_ASSIGN(src_delta, ssize_t, src->shared->size, size_t); + H5_CHECKED_ASSIGN(bkg_delta, ssize_t, dst->shared->size, size_t); + } /* end else-if */ + else { + H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); + src_delta = -(ssize_t)src->shared->size; + H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); + bkg_delta = -(ssize_t)dst->shared->size; + xbuf += (nelmts - 1) * src->shared->size; + xbkg += (nelmts - 1) * dst->shared->size; + } /* end else */ + + /* Conversion loop... */ + for (elmtno = 0; elmtno < nelmts; elmtno++) { + /* + * For each source member which will be present in the + * destination, convert the member to the destination type unless + * it is larger than the source type. Then move the member to the + * left-most unoccupied position in the buffer. This makes the + * data point as small as possible with all the free space on the + * right side. + */ + tmp_conv_ctx.u.conv.recursive = true; + for (u = 0, offset = 0; u < src->shared->u.compnd.nmembs; u++) { + if (src2dst[u] < 0) + continue; /*subsetting*/ + src_memb = src->shared->u.compnd.memb + u; + dst_memb = dst->shared->u.compnd.memb + src2dst[u]; + + if (dst_memb->size <= src_memb->size) { + /* Update IDs in conversion context */ + tmp_conv_ctx.u.conv.src_type_id = priv->src_memb_id[u]; + tmp_conv_ctx.u.conv.dst_type_id = priv->dst_memb_id[src2dst[u]]; + + if (H5T_convert_with_ctx(priv->memb_path[u], priv->src_memb[u], + priv->dst_memb[src2dst[u]], &tmp_conv_ctx, (size_t)1, + (size_t)0, (size_t)0, /*no striding (packed array)*/ + xbuf + src_memb->offset, xbkg + dst_memb->offset) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "unable to convert compound datatype member"); + + memmove(xbuf + offset, xbuf + src_memb->offset, dst_memb->size); + offset += dst_memb->size; + } /* end if */ + else { + memmove(xbuf + offset, xbuf + src_memb->offset, src_memb->size); + offset += src_memb->size; + } /* end else */ + } /* end for */ + tmp_conv_ctx.u.conv.recursive = false; + + /* + * For each source member which will be present in the + * destination, convert the member to the destination type if it + * is larger than the source type (that is, has not been converted + * yet). Then copy the member to the destination offset in the + * background buffer. + */ + tmp_conv_ctx.u.conv.recursive = true; + H5_CHECK_OVERFLOW(src->shared->u.compnd.nmembs, size_t, int); + for (int i = (int)src->shared->u.compnd.nmembs - 1; i >= 0; --i) { + if (src2dst[i] < 0) + continue; /*subsetting*/ + src_memb = src->shared->u.compnd.memb + i; + dst_memb = dst->shared->u.compnd.memb + src2dst[i]; + + if (dst_memb->size > src_memb->size) { + /* Update IDs in conversion context */ + tmp_conv_ctx.u.conv.src_type_id = priv->src_memb_id[i]; + tmp_conv_ctx.u.conv.dst_type_id = priv->dst_memb_id[src2dst[i]]; + + offset -= src_memb->size; + if (H5T_convert_with_ctx(priv->memb_path[i], priv->src_memb[i], + priv->dst_memb[src2dst[i]], &tmp_conv_ctx, (size_t)1, + (size_t)0, (size_t)0, /*no striding (packed array)*/ + xbuf + offset, xbkg + dst_memb->offset) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "unable to convert compound datatype member"); + } /* end if */ + else + offset -= dst_memb->size; + memcpy(xbkg + dst_memb->offset, xbuf + offset, dst_memb->size); + } /* end for */ + tmp_conv_ctx.u.conv.recursive = false; + + assert(0 == offset); + + /* + * Update pointers + */ + xbuf += src_delta; + xbkg += bkg_delta; + } /* end for */ + + /* If the bkg_delta was set to -(dst->shared->size), make it positive now */ + if (buf_stride == 0 && dst->shared->size > src->shared->size) + H5_CHECKED_ASSIGN(bkg_delta, ssize_t, dst->shared->size, size_t); + + /* + * Copy the background buffer back into the in-place conversion + * buffer. + */ + for (xbuf = buf, xbkg = bkg, elmtno = 0; elmtno < nelmts; elmtno++) { + memcpy(xbuf, xbkg, dst->shared->size); + xbuf += buf_stride ? buf_stride : dst->shared->size; + xbkg += bkg_delta; + } /* end for */ + break; + + default: + /* Some other command we don't know about yet.*/ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_struct() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_struct_opt + * + * Purpose: Converts between compound datatypes in a manner more + * efficient than the general-purpose H5T__conv_struct() + * function. This function isn't applicable if the destination + * is larger than the source type. This is a soft conversion + * function. The algorithm is basically: + * + * For each member of the struct + * If sizeof destination type <= sizeof source type then + * Convert member to destination type for all elements + * Move memb to BKG buffer for all elements + * Else + * Move member as far left as possible for all elements + * + * For each member of the struct (in reverse order) + * If not destination type then + * Convert member to destination type for all elements + * Move member to correct position in BKG for all elements + * + * Copy BKG to BUF for all elements + * + * Special case when the source and destination members + * are a subset of each other, and the order is the same, and + * no conversion is needed. For example: + * + * struct source { struct destination { + * TYPE1 A; --> TYPE1 A; + * TYPE2 B; --> TYPE2 B; + * TYPE3 C; --> TYPE3 C; + * }; TYPE4 D; + * TYPE5 E; + * }; + * + * The optimization is simply moving data to the appropriate + * places in the buffer. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_struct_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf, void *_bkg) +{ + uint8_t *buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ + uint8_t *bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ + uint8_t *xbuf = NULL; /*temporary pointer into `buf' */ + uint8_t *xbkg = NULL; /*temporary pointer into `bkg' */ + int *src2dst = NULL; /*maps src member to dst member */ + H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/ + H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */ + size_t offset; /*byte offset wrt struct */ + size_t elmtno; /*element counter */ + size_t copy_size; /*size of element for copying */ + H5T_conv_struct_t *priv = NULL; /*private data */ + H5T_conv_ctx_t tmp_conv_ctx = {0}; /*temporary conversion context */ + bool no_stride = false; /*flag to indicate no stride */ + unsigned u; /*counters */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* + * First, determine if this conversion function applies to the + * conversion path SRC-->DST. If not, return failure; + * otherwise initialize the `priv' field of `cdata' with information + * that remains (almost) constant for this conversion path. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (H5T_COMPOUND != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype"); + if (H5T_COMPOUND != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype"); + + /* Initialize data which is relatively constant */ + if (H5T__conv_struct_init(src, dst, cdata, conv_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); + priv = (H5T_conv_struct_t *)(cdata->priv); + src2dst = priv->src2dst; + + /* + * If the destination type is not larger than the source type then + * this conversion function is guaranteed to work (provided all + * members can be converted also). Otherwise the determination is + * quite a bit more complicated. Essentially we have to make sure + * that there is always room in the source buffer to do the + * conversion of a member in place. This is basically the same pair + * of loops as in the actual conversion except it checks that there + * is room for each conversion instead of actually doing anything. + */ + if (dst->shared->size > src->shared->size) { + for (u = 0, offset = 0; u < src->shared->u.compnd.nmembs; u++) { + if (src2dst[u] < 0) + continue; + src_memb = src->shared->u.compnd.memb + u; + dst_memb = dst->shared->u.compnd.memb + src2dst[u]; + if (dst_memb->size > src_memb->size) + offset += src_memb->size; + } /* end for */ + H5_CHECK_OVERFLOW(src->shared->u.compnd.nmembs, size_t, int); + for (int i = (int)src->shared->u.compnd.nmembs - 1; i >= 0; --i) { + if (src2dst[i] < 0) + continue; + src_memb = src->shared->u.compnd.memb + i; + dst_memb = dst->shared->u.compnd.memb + src2dst[i]; + if (dst_memb->size > src_memb->size) { + offset -= src_memb->size; + if (dst_memb->size > src->shared->size - offset) { + H5T__conv_struct_free(priv); + cdata->priv = NULL; + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "conversion is unsupported by this function"); + } /* end if */ + } /* end if */ + } /* end for */ + } /* end if */ + break; + + case H5T_CONV_FREE: { + /* + * Free the private conversion data. + */ + herr_t status = H5T__conv_struct_free((H5T_conv_struct_t *)(cdata->priv)); + cdata->priv = NULL; + if (status < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free private conversion data"); + + break; + } + + case H5T_CONV_CONV: + /* + * Conversion. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + if (!bkg) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid background buffer pointer"); + + /* Initialize temporary conversion context */ + tmp_conv_ctx = *conv_ctx; + + /* Update cached data if necessary */ + if (cdata->recalc && H5T__conv_struct_init(src, dst, cdata, conv_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); + priv = (H5T_conv_struct_t *)(cdata->priv); + assert(priv); + src2dst = priv->src2dst; + assert(cdata->need_bkg); + + /* + * Insure that members are sorted. + */ + H5T__sort_value(src, NULL); + H5T__sort_value(dst, NULL); + + /* + * Calculate strides. If BUF_STRIDE is non-zero then convert one + * data element at every BUF_STRIDE bytes through the main buffer + * (BUF), leaving the result of each conversion at the same + * location; otherwise assume the source and destination data are + * packed tightly based on src->shared->size and dst->shared->size. Also, if + * BUF_STRIDE and BKG_STRIDE are both non-zero then place + * background data into the BKG buffer at multiples of BKG_STRIDE; + * otherwise assume BKG buffer is the packed destination datatype. + */ + if (!buf_stride || !bkg_stride) + bkg_stride = dst->shared->size; + if (!buf_stride) { + no_stride = true; + buf_stride = src->shared->size; + } /* end if */ + + if (priv->subset_info.subset == H5T_SUBSET_SRC || priv->subset_info.subset == H5T_SUBSET_DST) { + /* If the optimization flag is set to indicate source members are a subset and + * in the top of the destination, simply copy the source members to background buffer. + */ + xbuf = buf; + xbkg = bkg; + copy_size = priv->subset_info.copy_size; + + for (elmtno = 0; elmtno < nelmts; elmtno++) { + memcpy(xbkg, xbuf, copy_size); + + /* Update pointers */ + xbuf += buf_stride; + xbkg += bkg_stride; + } /* end for */ + } /* end if */ + else { + /* + * For each member where the destination is not larger than the + * source, stride through all the elements converting only that member + * in each element and then copying the element to its final + * destination in the bkg buffer. Otherwise move the element as far + * left as possible in the buffer. + */ + tmp_conv_ctx.u.conv.recursive = true; + for (u = 0, offset = 0; u < src->shared->u.compnd.nmembs; u++) { + if (src2dst[u] < 0) + continue; /*subsetting*/ + src_memb = src->shared->u.compnd.memb + u; + dst_memb = dst->shared->u.compnd.memb + src2dst[u]; + + if (dst_memb->size <= src_memb->size) { + /* Update IDs in conversion context */ + tmp_conv_ctx.u.conv.src_type_id = priv->src_memb_id[u]; + tmp_conv_ctx.u.conv.dst_type_id = priv->dst_memb_id[src2dst[u]]; + + xbuf = buf + src_memb->offset; + xbkg = bkg + dst_memb->offset; + if (H5T_convert_with_ctx(priv->memb_path[u], priv->src_memb[u], + priv->dst_memb[src2dst[u]], &tmp_conv_ctx, nelmts, + buf_stride, bkg_stride, xbuf, xbkg) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "unable to convert compound datatype member"); + + for (elmtno = 0; elmtno < nelmts; elmtno++) { + memcpy(xbkg, xbuf, dst_memb->size); + xbuf += buf_stride; + xbkg += bkg_stride; + } /* end for */ + } /* end if */ + else { + for (xbuf = buf, elmtno = 0; elmtno < nelmts; elmtno++) { + memmove(xbuf + offset, xbuf + src_memb->offset, src_memb->size); + xbuf += buf_stride; + } /* end for */ + offset += src_memb->size; + } /* end else */ + } /* end else */ + tmp_conv_ctx.u.conv.recursive = false; + + /* + * Work from right to left, converting those members that weren't + * converted in the previous loop (those members where the destination + * is larger than the source) and them to their final position in the + * bkg buffer. + */ + tmp_conv_ctx.u.conv.recursive = true; + H5_CHECK_OVERFLOW(src->shared->u.compnd.nmembs, size_t, int); + for (int i = (int)src->shared->u.compnd.nmembs - 1; i >= 0; --i) { + if (src2dst[i] < 0) + continue; + src_memb = src->shared->u.compnd.memb + i; + dst_memb = dst->shared->u.compnd.memb + src2dst[i]; + + if (dst_memb->size > src_memb->size) { + /* Update IDs in conversion context */ + tmp_conv_ctx.u.conv.src_type_id = priv->src_memb_id[i]; + tmp_conv_ctx.u.conv.dst_type_id = priv->dst_memb_id[src2dst[i]]; + + offset -= src_memb->size; + xbuf = buf + offset; + xbkg = bkg + dst_memb->offset; + if (H5T_convert_with_ctx(priv->memb_path[i], priv->src_memb[i], + priv->dst_memb[src2dst[i]], &tmp_conv_ctx, nelmts, + buf_stride, bkg_stride, xbuf, xbkg) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "unable to convert compound datatype member"); + for (elmtno = 0; elmtno < nelmts; elmtno++) { + memcpy(xbkg, xbuf, dst_memb->size); + xbuf += buf_stride; + xbkg += bkg_stride; + } /* end for */ + } /* end if */ + } /* end for */ + tmp_conv_ctx.u.conv.recursive = false; + } /* end else */ + + if (no_stride) + buf_stride = dst->shared->size; + + /* Move background buffer into result buffer */ + for (xbuf = buf, xbkg = bkg, elmtno = 0; elmtno < nelmts; elmtno++) { + memcpy(xbuf, xbkg, dst->shared->size); + xbuf += buf_stride; + xbkg += bkg_stride; + } /* end for */ + break; + + default: + /* Some other command we don't know about yet.*/ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_struct_opt() */ diff --git a/src/H5Tconv_compound.h b/src/H5Tconv_compound.h new file mode 100644 index 00000000000..02d3150c4e3 --- /dev/null +++ b/src/H5Tconv_compound.h @@ -0,0 +1,41 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_compound_H +#define H5Tconv_compound_H + +/* Private headers needed by this file */ +#include "H5Tpkg.h" + +/***********************/ +/* Function Prototypes */ +/***********************/ + +H5_DLL H5T_subset_info_t *H5T__conv_struct_subset(const H5T_cdata_t *cdata); + +/****************************************/ +/* Soft (emulated) conversion functions */ +/****************************************/ + +/* Conversion functions between compound datatypes */ +H5_DLL herr_t H5T__conv_struct(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); +H5_DLL herr_t H5T__conv_struct_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); + +/*********************************************/ +/* Hard (compiler cast) conversion functions */ +/*********************************************/ + +#endif /* H5Tconv_compound_H */ diff --git a/src/H5Tconv_enum.c b/src/H5Tconv_enum.c new file mode 100644 index 00000000000..cfa86071987 --- /dev/null +++ b/src/H5Tconv_enum.c @@ -0,0 +1,544 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Datatype conversion functions for enum datatypes + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5Eprivate.h" +#include "H5Tconv.h" +#include "H5Tconv_enum.h" + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Private conversion data for enum datatypes */ +typedef struct H5T_conv_enum_t { + H5T_t *src_copy; /* cached copy of source datatype */ + H5T_t *dst_copy; /* cached copy of destination datatype */ + int base; /* lowest `in' value */ + unsigned length; /* num elements in arrays */ + int *src2dst; /* map from src to dst index */ +} H5T_conv_enum_t; + +/********************/ +/* Local Prototypes */ +/********************/ + +static herr_t H5T__conv_enum_init(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx); +static herr_t H5T__conv_enum_free(H5T_conv_enum_t *priv); + +/*------------------------------------------------------------------------- + * Function: H5T__conv_enum_init + * + * Purpose: Initialize private data for enum datatype conversions. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__conv_enum_init(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx) +{ + H5T_conv_enum_t *priv = NULL; /* Private conversion data */ + int *map = NULL; /* Map from src value to dst idx */ + bool rebuild_cache = false; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + cdata->need_bkg = H5T_BKG_NO; + + priv = (H5T_conv_enum_t *)(cdata->priv); + if (!priv) { + if (NULL == (priv = (H5T_conv_enum_t *)(cdata->priv = calloc(1, sizeof(*priv))))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + rebuild_cache = true; + } + else { + /* Check if we need to rebuild our cache. For now, treat + * enums as different even if one is just a subset of the + * other + */ + if (cdata->command == H5T_CONV_CONV && conv_ctx->u.conv.recursive) + /* Recursive conversion; we can reuse the cache */ + rebuild_cache = false; + else { + if (0 != H5T_cmp(src, priv->src_copy, false) || 0 != H5T_cmp(dst, priv->dst_copy, false)) + rebuild_cache = true; + } + } + + if (rebuild_cache) { + H5T_shared_t *src_sh; + H5T_shared_t *dst_sh; + size_t src_nmembs; + size_t dst_nmembs; + void *tmp_realloc; + + /* Allocate everything we need to cache */ + if (priv->src_copy && H5T_close(priv->src_copy) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied source datatype"); + if (priv->dst_copy && H5T_close(priv->dst_copy) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied destination datatype"); + + if (NULL == (priv->src_copy = H5T_copy(src, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy source datatype"); + if (NULL == (priv->dst_copy = H5T_copy(dst, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy destination datatype"); + + /* Nothing more to do if enum has no members */ + if (0 == src->shared->u.enumer.nmembs) + HGOTO_DONE(SUCCEED); + + src_sh = priv->src_copy->shared; + dst_sh = priv->src_copy->shared; + src_nmembs = src_sh->u.enumer.nmembs; + dst_nmembs = dst_sh->u.enumer.nmembs; + + if (NULL == (tmp_realloc = realloc(priv->src2dst, src_nmembs * sizeof(int)))) { + free(priv->src2dst); + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "unable to allocate space for source to destination enum mapping"); + } + priv->src2dst = tmp_realloc; + + /* + * Check that the source symbol names are a subset of the destination + * symbol names and build a map from source member index to destination + * member index. + */ + H5T__sort_name(priv->src_copy, NULL); + H5T__sort_name(priv->dst_copy, NULL); + for (size_t i = 0, j = 0; i < src_nmembs && j < dst_nmembs; i++, j++) { + char *src_name = src_sh->u.enumer.name[i]; + char *dst_name = dst_sh->u.enumer.name[j]; + + while (j < dst_nmembs && strcmp(src_name, dst_name) != 0) + j++; + + if (j >= dst_nmembs) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "source enum type is not a subset of destination enum type"); + + H5_CHECKED_ASSIGN(priv->src2dst[i], int, j, size_t); + } + + /* + * The conversion function will use an O(log N) lookup method for each + * value converted. However, if all of the following constraints are met + * then we can build a perfect hash table and use an O(1) lookup method. + * + * A: The source datatype size matches one of our native datatype + * sizes. + * + * B: After casting the source value bit pattern to a native type + * the size of the range of values is less than 20% larger than + * the number of values. + * + * If this special case is met then we use the source bit pattern cast as + * a native integer type as an index into the `val2dst'. The values of + * that array are the index numbers in the destination type or negative + * if the entry is unused. + * + * (This optimized algorithm doesn't work when the byte orders are different. + * The code such as "n = *((int *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * + * src_sh->size))));" can change the value significantly. i.g. if the source value is big-endian + * 0x0000000f, executing the casting on little-endian machine will get a big number 0x0f000000. Then + * it can't meet the condition "if (src_nmembs < 2 || ((double)length / (double)src_nmembs < + * (double)(1.2F)))" Because this is the optimized code, we won't fix it. It should still work in some + * situations. SLU - 2011/5/24) + */ + if (1 == src_sh->size || sizeof(short) == src_sh->size || sizeof(int) == src_sh->size) { + unsigned length; + int domain[2] = {0, 0}; /* Min and max source values */ + + for (size_t i = 0; i < src_nmembs; i++) { + int n; + + if (1 == src_sh->size) + n = *((signed char *)((uint8_t *)src_sh->u.enumer.value + i)); + else if (sizeof(short) == src_sh->size) + n = *((short *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * src_sh->size)))); + else + n = *((int *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * src_sh->size)))); + if (0 == i) { + domain[0] = domain[1] = n; + } + else { + domain[0] = MIN(domain[0], n); + domain[1] = MAX(domain[1], n); + } + } + assert(domain[1] >= domain[0]); + + length = (unsigned)(domain[1] - domain[0]) + 1; + if (src_nmembs < 2 || ((double)length / (double)src_nmembs < (double)(1.2F))) { + priv->base = domain[0]; + priv->length = length; + + if (NULL == (map = malloc(length * sizeof(int)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed"); + + for (size_t i = 0; i < length; i++) + map[i] = -1; /*entry unused*/ + + for (size_t i = 0; i < src_nmembs; i++) { + int n; + + if (1 == src_sh->size) + n = *((signed char *)((uint8_t *)src_sh->u.enumer.value + i)); + else if (sizeof(short) == src_sh->size) + n = *((short *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * src_sh->size)))); + else + n = *((int *)((void *)((uint8_t *)src_sh->u.enumer.value + (i * src_sh->size)))); + n -= priv->base; + assert(n >= 0 && (unsigned)n < priv->length); + assert(map[n] < 0); + map[n] = priv->src2dst[i]; + } + + /* + * Replace original src2dst array with our new one. The original + * was indexed by source member number while the new one is + * indexed by source values. + */ + free(priv->src2dst); + priv->src2dst = map; + + HGOTO_DONE(SUCCEED); + } + } + + /* Sort source type by value and adjust src2dst[] appropriately */ + H5T__sort_value(priv->src_copy, priv->src2dst); + } + +#ifdef H5T_DEBUG + if (H5DEBUG(T)) { + fprintf(H5DEBUG(T), " Using %s mapping function%s\n", priv->length ? "O(1)" : "O(log N)", + priv->length ? "" : ", where N is the number of enum members"); + } +#endif + +done: + if (ret_value < 0 && priv) { + if (map) { + free(map); + priv->src2dst = NULL; + } + + if (H5T__conv_enum_free(priv) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free enum conversion data"); + + cdata->priv = NULL; + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_enum_init() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_enum_free + * + * Purpose: Free the private data structure used by the enum conversion + * functions. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__conv_enum_free(H5T_conv_enum_t *priv) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + if (priv) { + free(priv->src2dst); + + if (priv->dst_copy && H5T_close(priv->dst_copy) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied source datatype"); + if (priv->src_copy && H5T_close(priv->src_copy) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied destination datatype"); + + free(priv); + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_enum_free() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_enum + * + * Purpose: Converts one type of enumerated data to another. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_enum(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *_buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_conv_enum_t *priv = (H5T_conv_enum_t *)(cdata->priv); + H5T_shared_t *src_sh = NULL; + H5T_shared_t *dst_sh = NULL; + uint8_t *buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ + uint8_t *s = NULL, *d = NULL; /*src and dst BUF pointers */ + ssize_t src_delta, dst_delta; /*conversion strides */ + int n; /*src value cast as native int */ + H5T_conv_ret_t except_ret; /*return of callback function */ + size_t i; /*counters */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* + * Determine if this conversion function applies to the conversion + * path SRC->DST. If not return failure; otherwise initialize + * the `priv' field of `cdata' with information about the underlying + * integer conversion. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); + if (H5T_ENUM != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype"); + if (H5T_ENUM != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype"); + + if (H5T__conv_enum_init(src, dst, cdata, conv_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data"); + break; + + case H5T_CONV_FREE: { + herr_t status = H5T__conv_enum_free(priv); + cdata->priv = NULL; + if (status < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free private conversion data"); + + break; + } + + case H5T_CONV_CONV: + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + if (H5T_ENUM != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype"); + if (H5T_ENUM != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype"); + + /* Reuse cache if possible, rebuild otherwise */ + if (H5T__conv_enum_init(src, dst, cdata, conv_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data"); + + src_sh = priv->src_copy->shared; + dst_sh = priv->dst_copy->shared; + + /* + * Direction of conversion. + */ + if (buf_stride) { + H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); + src_delta = dst_delta = (ssize_t)buf_stride; + s = d = buf; + } + else if (dst_sh->size <= src_sh->size) { + H5_CHECKED_ASSIGN(src_delta, ssize_t, src_sh->size, size_t); + H5_CHECKED_ASSIGN(dst_delta, ssize_t, dst_sh->size, size_t); + s = d = buf; + } + else { + H5_CHECK_OVERFLOW(src_sh->size, size_t, ssize_t); + H5_CHECK_OVERFLOW(dst_sh->size, size_t, ssize_t); + src_delta = -(ssize_t)src_sh->size; + dst_delta = -(ssize_t)dst_sh->size; + s = buf + (nelmts - 1) * src_sh->size; + d = buf + (nelmts - 1) * dst_sh->size; + } + + if (priv->length) { + for (i = 0; i < nelmts; i++, s += src_delta, d += dst_delta) { + /* Use O(1) lookup */ + /* (The casting won't work when the byte orders are different. i.g. if the source value + * is big-endian 0x0000000f, the direct casting "n = *((int *)((void *)s));" will make + * it a big number 0x0f000000 on little-endian machine. But we won't fix it because it's + * an optimization code. Please also see the comment in the H5T__conv_enum_init() + * function. SLU - 2011/5/24) + */ + if (1 == src_sh->size) + n = *((signed char *)s); + else if (sizeof(short) == src_sh->size) + n = *((short *)((void *)s)); + else + n = *((int *)((void *)s)); + n -= priv->base; + if (n < 0 || (unsigned)n >= priv->length || priv->src2dst[n] < 0) { + /*overflow*/ + except_ret = H5T_CONV_UNHANDLED; + /*If user's exception handler is present, use it*/ + if (conv_ctx->u.conv.cb_struct.func) + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, s, d, conv_ctx->u.conv.cb_struct.user_data); + + if (except_ret == H5T_CONV_UNHANDLED) + memset(d, 0xff, dst_sh->size); + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + } + else + H5MM_memcpy(d, + (uint8_t *)dst_sh->u.enumer.value + + ((unsigned)priv->src2dst[n] * dst_sh->size), + dst_sh->size); + } + } + else { + for (i = 0; i < nelmts; i++, s += src_delta, d += dst_delta) { + /* Use O(log N) lookup */ + unsigned lt = 0; + unsigned rt = src_sh->u.enumer.nmembs; + unsigned md = 0; + int cmp; + + while (lt < rt) { + md = (lt + rt) / 2; + cmp = + memcmp(s, (uint8_t *)src_sh->u.enumer.value + (md * src_sh->size), src_sh->size); + if (cmp < 0) + rt = md; + else if (cmp > 0) + lt = md + 1; + else + break; + } /* end while */ + if (lt >= rt) { + except_ret = H5T_CONV_UNHANDLED; + /*If user's exception handler is present, use it*/ + if (conv_ctx->u.conv.cb_struct.func) + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, s, d, conv_ctx->u.conv.cb_struct.user_data); + + if (except_ret == H5T_CONV_UNHANDLED) + memset(d, 0xff, dst_sh->size); + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + } /* end if */ + else { + assert(priv->src2dst[md] >= 0); + H5MM_memcpy(d, + (uint8_t *)dst_sh->u.enumer.value + + ((unsigned)priv->src2dst[md] * dst_sh->size), + dst_sh->size); + } /* end else */ + } + } + + break; + + default: + /* Some other command we don't know about yet.*/ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_enum() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_enum_numeric + * + * Purpose: Converts enumerated data to a numeric type (integer or + * floating-point number). This function is registered into + * the conversion table twice in H5T_init_interface in H5T.c. + * Once for enum-integer conversion. Once for enum-float + * conversion. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_enum_numeric(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, + size_t H5_ATTR_UNUSED buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *_buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_t *src_parent; /*parent type for src */ + H5T_path_t *tpath; /* Conversion information */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* + * Determine if this conversion function applies to the conversion + * path SRC->DST. If not, return failure. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); + if (H5T_ENUM != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "source type is not a H5T_ENUM datatype"); + if (H5T_INTEGER != dst->shared->type && H5T_FLOAT != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "destination is not an integer type"); + + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + + src_parent = src->shared->parent; + + if (NULL == (tpath = H5T_path_find(src_parent, dst))) { + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unable to convert between src and dest datatype"); + } + else if (!H5T_path_noop(tpath)) { + /* Convert the data */ + if (H5T_convert(tpath, src_parent, dst, nelmts, buf_stride, bkg_stride, _buf, bkg) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed"); + } + break; + + default: + /* Some other command we don't know about yet.*/ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_enum_numeric() */ diff --git a/src/H5Tconv_enum.h b/src/H5Tconv_enum.h new file mode 100644 index 00000000000..da836ce707e --- /dev/null +++ b/src/H5Tconv_enum.h @@ -0,0 +1,41 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_enum_H +#define H5Tconv_enum_H + +/* Private headers needed by this file */ +#include "H5Tpkg.h" + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/****************************************/ +/* Soft (emulated) conversion functions */ +/****************************************/ + +/* Conversion functions between enum datatypes */ +H5_DLL herr_t H5T__conv_enum(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions from enum datatype to another datatype class */ +H5_DLL herr_t H5T__conv_enum_numeric(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/*********************************************/ +/* Hard (compiler cast) conversion functions */ +/*********************************************/ + +#endif /* H5Tconv_enum_H */ diff --git a/src/H5Tconv_float.c b/src/H5Tconv_float.c new file mode 100644 index 00000000000..806a7261677 --- /dev/null +++ b/src/H5Tconv_float.c @@ -0,0 +1,2298 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Datatype conversion functions for floating-point datatypes + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5Tconv.h" +#include "H5Tconv_macros.h" +#include "H5Tconv_float.h" + +/*------------------------------------------------------------------------- + * Function: H5T__conv_f_f + * + * Purpose: Convert one floating point type to another. This is a catch + * all for floating point conversions and is probably not + * particularly fast! + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_f_f(const H5T_t *src_p, const H5T_t *dst_p, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + /* Traversal-related variables */ + H5T_atomic_t src; /*atomic source info */ + H5T_atomic_t dst; /*atomic destination info */ + ssize_t src_delta, dst_delta; /*source & destination stride */ + int direction; /*forward or backward traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ + size_t tsize; /*type size for swapping bytes */ + size_t olap; /*num overlapping elements */ + ssize_t bitno = 0; /*bit number */ + uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ + uint8_t *src_rev = NULL; /*order-reversed source buffer */ + uint8_t dbuf[64] = {0}; /*temp destination buffer */ + uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ + + /* Conversion-related variables */ + int64_t expo; /*exponent */ + hssize_t expo_max; /*maximum possible dst exponent */ + size_t msize = 0; /*useful size of mantissa in src*/ + size_t mpos; /*offset to useful mant is src */ + uint64_t sign; /*source sign bit value */ + size_t mrsh; /*amount to right shift mantissa*/ + bool carry = false; /*carry after rounding mantissa */ + size_t i; /*miscellaneous counters */ + size_t implied; /*destination implied bits */ + bool denormalized = false; /*is either source or destination denormalized?*/ + H5T_conv_ret_t except_ret; /*return of callback function */ + bool reverse; /*if reverse the order of destination */ + herr_t ret_value = SUCCEED; /*return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + if (NULL == src_p || NULL == dst_p) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + src = src_p->shared->u.atomic; + dst = dst_p->shared->u.atomic; + if (H5T_ORDER_LE != src.order && H5T_ORDER_BE != src.order && H5T_ORDER_VAX != src.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); + if (H5T_ORDER_LE != dst.order && H5T_ORDER_BE != dst.order && H5T_ORDER_VAX != dst.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); + if (dst_p->shared->size > sizeof(dbuf)) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); + if (8 * sizeof(expo) - 1 < src.u.f.esize || 8 * sizeof(expo) - 1 < dst.u.f.esize) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + if (NULL == src_p || NULL == dst_p) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + + src = src_p->shared->u.atomic; + dst = dst_p->shared->u.atomic; + expo_max = ((hssize_t)1 << dst.u.f.esize) - 1; + + /* + * Do we process the values from beginning to end or vice versa? Also, + * how many of the elements have the source and destination areas + * overlapping? + */ + if (src_p->shared->size == dst_p->shared->size || buf_stride) { + sp = dp = (uint8_t *)buf; + direction = 1; + olap = nelmts; + } + else if (src_p->shared->size >= dst_p->shared->size) { + double olap_d = + ceil((double)(dst_p->shared->size) / (double)(src_p->shared->size - dst_p->shared->size)); + olap = (size_t)olap_d; + sp = dp = (uint8_t *)buf; + direction = 1; + } + else { + double olap_d = + ceil((double)(src_p->shared->size) / (double)(dst_p->shared->size - src_p->shared->size)); + olap = (size_t)olap_d; + sp = (uint8_t *)buf + (nelmts - 1) * src_p->shared->size; + dp = (uint8_t *)buf + (nelmts - 1) * dst_p->shared->size; + direction = -1; + } + + /* + * Direction & size of buffer traversal. + */ + H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); + H5_CHECK_OVERFLOW(src_p->shared->size, size_t, ssize_t); + H5_CHECK_OVERFLOW(dst_p->shared->size, size_t, ssize_t); + src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src_p->shared->size); + dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst_p->shared->size); + + /* Allocate space for order-reversed source buffer */ + src_rev = (uint8_t *)H5MM_calloc(src_p->shared->size); + + /* The conversion loop */ + for (elmtno = 0; elmtno < nelmts; elmtno++) { + /* Set these variables to default */ + except_ret = H5T_CONV_UNHANDLED; + reverse = true; + + /* + * If the source and destination buffers overlap then use a + * temporary buffer for the destination. + */ + if (direction > 0) { + s = sp; + d = elmtno < olap ? dbuf : dp; + } + else { + s = sp; + d = elmtno + olap >= nelmts ? dbuf : dp; + } +#ifndef NDEBUG + /* I don't quite trust the overlap calculations yet */ + if (d == dbuf) { + assert((dp >= sp && dp < sp + src_p->shared->size) || + (sp >= dp && sp < dp + dst_p->shared->size)); + } + else { + assert((dp < sp && dp + dst_p->shared->size <= sp) || + (sp < dp && sp + src_p->shared->size <= dp)); + } +#endif + + /* + * Put the data in little endian order so our loops aren't so + * complicated. We'll do all the conversion stuff assuming + * little endian and then we'll fix the order at the end. + */ + if (H5T_ORDER_BE == src.order) { + half_size = src_p->shared->size / 2; + for (i = 0; i < half_size; i++) { + tmp1 = s[src_p->shared->size - (i + 1)]; + s[src_p->shared->size - (i + 1)] = s[i]; + s[i] = tmp1; + } + } + else if (H5T_ORDER_VAX == src.order) { + tsize = src_p->shared->size; + assert(0 == tsize % 2); + + for (i = 0; i < tsize; i += 4) { + tmp1 = s[i]; + tmp2 = s[i + 1]; + + s[i] = s[(tsize - 2) - i]; + s[i + 1] = s[(tsize - 1) - i]; + + s[(tsize - 2) - i] = tmp1; + s[(tsize - 1) - i] = tmp2; + } + } + + /* + * Find the sign bit value of the source. + */ + sign = H5T__bit_get_d(s, src.u.f.sign, (size_t)1); + + /* + * Check for special cases: +0, -0, +Inf, -Inf, NaN + */ + if (H5T__bit_find(s, src.u.f.mpos, src.u.f.msize, H5T_BIT_LSB, true) < 0) { + if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, true) < 0) { + /* +0 or -0 */ + H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); + H5T__bit_set(d, dst.u.f.epos, dst.u.f.esize, false); + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); + goto padding; + } + else if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { + /* +Inf or -Inf */ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + if (sign) + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_NINF, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + else + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_PINF, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); + H5T__bit_set(d, dst.u.f.epos, dst.u.f.esize, true); + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); + /*If the destination no implied mantissa bit, we'll need to set + *the 1st bit of mantissa to 1. The Intel-Linux long double is + *this case.*/ + if (H5T_NORM_NONE == dst.u.f.norm) + H5T__bit_set(d, dst.u.f.mpos + dst.u.f.msize - 1, (size_t)1, true); + } + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + + goto padding; + } + } + else if (H5T_NORM_NONE == src.u.f.norm && + H5T__bit_find(s, src.u.f.mpos, src.u.f.msize - 1, H5T_BIT_LSB, true) < 0 && + H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { + /*This is a special case for the source of no implied mantissa bit. + *If the exponent bits are all 1s and only the 1st bit of mantissa + *is set to 1. It's infinity. The Intel-Linux "long double" is this case.*/ + /* +Inf or -Inf */ + if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + if (sign) + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_NINF, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + else + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_PINF, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); + H5T__bit_set(d, dst.u.f.epos, dst.u.f.esize, true); + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); + /*If the destination no implied mantissa bit, we'll need to set + *the 1st bit of mantissa to 1. The Intel-Linux long double is + *this case.*/ + if (H5T_NORM_NONE == dst.u.f.norm) + H5T__bit_set(d, dst.u.f.mpos + dst.u.f.msize - 1, (size_t)1, true); + } + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); + + goto padding; + /* Temporary solution to handle VAX special values. + * Note that even though we don't support VAX anymore, we + * still need to handle legacy VAX files so this code must + * remain in place. + */ + } + else if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { + /* NaN */ + if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_NAN, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, + src_rev, d, conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + /* There are many NaN values, so we just set all bits of + * the significand. */ + H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); + H5T__bit_set(d, dst.u.f.epos, dst.u.f.esize, true); + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, true); + } + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); + + goto padding; + } + + /* + * Get the exponent as an unsigned quantity from the section of + * the source bit field where it's located. Don't worry about + * the exponent bias yet. + */ + expo = (int64_t)H5T__bit_get_d(s, src.u.f.epos, src.u.f.esize); + + if (expo == 0) + denormalized = true; + + /* + * Set markers for the source mantissa, excluding the leading `1' + * (might be implied). + */ + implied = 1; + mpos = src.u.f.mpos; + mrsh = 0; + if (0 == expo || H5T_NORM_NONE == src.u.f.norm) { + if ((bitno = H5T__bit_find(s, src.u.f.mpos, src.u.f.msize, H5T_BIT_MSB, true)) > 0) { + msize = (size_t)bitno; + } + else if (0 == bitno) { + msize = 1; + H5T__bit_set(s, src.u.f.mpos, (size_t)1, false); + } + } + else if (H5T_NORM_IMPLIED == src.u.f.norm) { + msize = src.u.f.msize; + } + else { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "normalization method not implemented yet"); + } + + /* + * The sign for the destination is the same as the sign for the + * source in all cases. + */ + H5T__bit_copy(d, dst.u.f.sign, s, src.u.f.sign, (size_t)1); + + /* + * Calculate the true source exponent by adjusting according to + * the source exponent bias. + */ + if (0 == expo || H5T_NORM_NONE == src.u.f.norm) { + assert(bitno >= 0); + expo -= (int64_t)((src.u.f.ebias - 1) + (src.u.f.msize - (size_t)bitno)); + } + else if (H5T_NORM_IMPLIED == src.u.f.norm) { + expo -= (int64_t)src.u.f.ebias; + } + else { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "normalization method not implemented yet"); + } + + /* + * If the destination is not normalized then right shift the + * mantissa by one. + */ + if (H5T_NORM_NONE == dst.u.f.norm) + mrsh++; + + /* + * Calculate the destination exponent by adding the destination + * bias and clipping by the minimum and maximum possible + * destination exponent values. + */ + expo += (int64_t)dst.u.f.ebias; + + if (expo < -(hssize_t)(dst.u.f.msize)) { + /* The exponent is way too small. Result is zero. */ + expo = 0; + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); + msize = 0; + } + else if (expo <= 0) { + /* + * The exponent is too small to fit in the exponent field, + * but by shifting the mantissa to the right we can + * accommodate that value. The mantissa of course is no + * longer normalized. + */ + mrsh += (size_t)(1 - expo); + expo = 0; + denormalized = true; + } + else if (expo >= expo_max) { + /* + * The exponent is too large to fit in the available region + * or it results in the maximum possible value. Use positive + * or negative infinity instead unless the application + * specifies something else. Before calling the overflow + * handler make sure the source buffer we hand it is in the + * original byte order. + */ + if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + expo = expo_max; + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); + msize = 0; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) { + reverse = false; + goto next; + } + } + + /* + * If the destination mantissa is smaller than the source + * mantissa then round the source mantissa. Rounding may cause a + * carry in which case the exponent has to be re-evaluated for + * overflow. That is, if `carry' is clear then the implied + * mantissa bit is `1', else it is `10' binary. + */ + if (msize > 0 && mrsh <= dst.u.f.msize && mrsh + msize > dst.u.f.msize) { + bitno = (ssize_t)(mrsh + msize - dst.u.f.msize); + assert(bitno >= 0 && (size_t)bitno <= msize); + /* If the 1st bit being cut off is set and source isn't denormalized.*/ + if (H5T__bit_get_d(s, (mpos + (size_t)bitno) - 1, (size_t)1) && !denormalized) { + /* Don't do rounding if exponent is 111...110 and mantissa is 111...11. + * To do rounding and increment exponent in this case will create an infinity value.*/ + if ((H5T__bit_find(s, mpos + (size_t)bitno, msize - (size_t)bitno, H5T_BIT_LSB, + false) >= 0 || + expo < expo_max - 1)) { + carry = H5T__bit_inc(s, mpos + (size_t)bitno - 1, 1 + msize - (size_t)bitno); + if (carry) + implied = 2; + } + } + else if (H5T__bit_get_d(s, (mpos + (size_t)bitno) - 1, (size_t)1) && denormalized) + /* For either source or destination, denormalized value doesn't increment carry.*/ + H5T__bit_inc(s, mpos + (size_t)bitno - 1, 1 + msize - (size_t)bitno); + } + else + carry = false; + + /* + * Write the mantissa to the destination + */ + if (mrsh > dst.u.f.msize + 1) { + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); + } + else if (mrsh == dst.u.f.msize + 1) { + H5T__bit_set(d, dst.u.f.mpos + 1, dst.u.f.msize - 1, false); + H5T__bit_set(d, dst.u.f.mpos, (size_t)1, true); + } + else if (mrsh == dst.u.f.msize) { + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); + H5T__bit_set_d(d, dst.u.f.mpos, MIN(2, dst.u.f.msize), (hsize_t)implied); + } + else { + if (mrsh > 0) { + H5T__bit_set(d, dst.u.f.mpos + dst.u.f.msize - mrsh, mrsh, false); + H5T__bit_set_d(d, dst.u.f.mpos + dst.u.f.msize - mrsh, (size_t)2, (hsize_t)implied); + } + if (mrsh + msize >= dst.u.f.msize) { + H5T__bit_copy(d, dst.u.f.mpos, s, (mpos + msize + mrsh - dst.u.f.msize), + dst.u.f.msize - mrsh); + } + else { + H5T__bit_copy(d, dst.u.f.mpos + dst.u.f.msize - (mrsh + msize), s, mpos, msize); + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize - (mrsh + msize), false); + } + } + + /* Write the exponent */ + if (carry) { + expo++; + if (expo >= expo_max) { + /* + * The exponent is too large to fit in the available + * region or it results in the maximum possible value. + * Use positive or negative infinity instead unless the + * application specifies something else. Before + * calling the overflow handler make sure the source + * buffer we hand it is in the original byte order. + */ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + expo = expo_max; + H5T__bit_set(d, dst.u.f.mpos, dst.u.f.msize, false); + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) { + reverse = false; + goto next; + } + } + } + /*reset CARRY*/ + carry = false; + + H5_CHECK_OVERFLOW(expo, hssize_t, hsize_t); + H5T__bit_set_d(d, dst.u.f.epos, dst.u.f.esize, (hsize_t)expo); + +padding: + + /* + * Set external padding areas + */ + if (dst.offset > 0) { + assert(H5T_PAD_ZERO == dst.lsb_pad || H5T_PAD_ONE == dst.lsb_pad); + H5T__bit_set(d, (size_t)0, dst.offset, (bool)(H5T_PAD_ONE == dst.lsb_pad)); + } + if (dst.offset + dst.prec != 8 * dst_p->shared->size) { + assert(H5T_PAD_ZERO == dst.msb_pad || H5T_PAD_ONE == dst.msb_pad); + H5T__bit_set(d, dst.offset + dst.prec, 8 * dst_p->shared->size - (dst.offset + dst.prec), + (bool)(H5T_PAD_ONE == dst.msb_pad)); + } + + /* + * Put the destination in the correct byte order. See note at + * beginning of loop. + */ + if (H5T_ORDER_BE == dst.order && reverse) { + half_size = dst_p->shared->size / 2; + for (i = 0; i < half_size; i++) { + uint8_t tmp = d[dst_p->shared->size - (i + 1)]; + d[dst_p->shared->size - (i + 1)] = d[i]; + d[i] = tmp; + } + } + else if (H5T_ORDER_VAX == dst.order && reverse) { + tsize = dst_p->shared->size; + assert(0 == tsize % 2); + + for (i = 0; i < tsize; i += 4) { + tmp1 = d[i]; + tmp2 = d[i + 1]; + + d[i] = d[(tsize - 2) - i]; + d[i + 1] = d[(tsize - 1) - i]; + + d[(tsize - 2) - i] = tmp1; + d[(tsize - 1) - i] = tmp2; + } + } + + /* + * If we had used a temporary buffer for the destination then we + * should copy the value to the true destination buffer. + */ +next: + if (d == dbuf) + H5MM_memcpy(dp, d, dst_p->shared->size); + + /* Advance source & destination pointers by delta amounts */ + sp += src_delta; + dp += dst_delta; + } + + break; + + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + if (src_rev) + H5MM_free(src_rev); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_f_f() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_f_i + * + * Purpose: Convert one floating-point type to an integer. This is + * the catch-all function for float-integer conversions and + * is probably not particularly fast. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_f_i(const H5T_t *src_p, const H5T_t *dst_p, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + /* Traversal-related variables */ + H5T_atomic_t src; /*atomic source info */ + H5T_atomic_t dst; /*atomic destination info */ + int direction; /*forward or backward traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ + size_t tsize; /*type size for swapping bytes */ + size_t olap; /*num overlapping elements */ + uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ + uint8_t *src_rev = NULL; /*order-reversed source buffer */ + uint8_t dbuf[64] = {0}; /*temp destination buffer */ + uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ + + /* Conversion-related variables */ + hssize_t expo; /*source exponent */ + hssize_t sign; /*source sign bit value */ + uint8_t *int_buf = NULL; /*buffer for temporary value */ + size_t buf_size; /*buffer size for temporary value */ + size_t i; /*miscellaneous counters */ + ssize_t msb_pos_s; /*first bit(MSB) in an integer */ + ssize_t new_msb_pos; /*MSB position after shifting mantissa by exponent */ + hssize_t shift_val; /*shift value when shifting mantissa by exponent */ + bool truncated; /*if fraction value is dropped */ + bool reverse; /*if reverse order of destination at the end */ + H5T_conv_ret_t except_ret; /*return of callback function */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + if (NULL == src_p || NULL == dst_p) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + src = src_p->shared->u.atomic; + dst = dst_p->shared->u.atomic; + if (H5T_ORDER_LE != src.order && H5T_ORDER_BE != src.order && H5T_ORDER_VAX != src.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); + if (dst_p->shared->size > sizeof(dbuf)) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); + if (8 * sizeof(expo) - 1 < src.u.f.esize) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + if (NULL == src_p || NULL == dst_p) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + + src = src_p->shared->u.atomic; + dst = dst_p->shared->u.atomic; + + /* + * Do we process the values from beginning to end or vice versa? Also, + * how many of the elements have the source and destination areas + * overlapping? + */ + if (src_p->shared->size == dst_p->shared->size || buf_stride) { + sp = dp = (uint8_t *)buf; + direction = 1; + olap = nelmts; + } + else if (src_p->shared->size >= dst_p->shared->size) { + double olap_d = + ceil((double)(dst_p->shared->size) / (double)(src_p->shared->size - dst_p->shared->size)); + olap = (size_t)olap_d; + sp = dp = (uint8_t *)buf; + direction = 1; + } + else { + double olap_d = + ceil((double)(src_p->shared->size) / (double)(dst_p->shared->size - src_p->shared->size)); + olap = (size_t)olap_d; + sp = (uint8_t *)buf + (nelmts - 1) * src_p->shared->size; + dp = (uint8_t *)buf + (nelmts - 1) * dst_p->shared->size; + direction = -1; + } + + /* Allocate enough space for the buffer holding temporary + * converted value + */ + if (dst.prec / 8 > src_p->shared->size) + buf_size = (dst.prec + 7) / 8; + else + buf_size = src_p->shared->size; + int_buf = (uint8_t *)H5MM_calloc(buf_size); + + /* Allocate space for order-reversed source buffer */ + src_rev = (uint8_t *)H5MM_calloc(src_p->shared->size); + + /* The conversion loop */ + for (elmtno = 0; elmtno < nelmts; elmtno++) { + /* Set these variables to default */ + except_ret = H5T_CONV_UNHANDLED; + truncated = false; + reverse = true; + + /* + * If the source and destination buffers overlap then use a + * temporary buffer for the destination. + */ + if (direction > 0) { + s = sp; + d = elmtno < olap ? dbuf : dp; + } + else { + s = sp; + d = elmtno + olap >= nelmts ? dbuf : dp; + } +#ifndef NDEBUG + /* I don't quite trust the overlap calculations yet */ + if (d == dbuf) { + assert((dp >= sp && dp < sp + src_p->shared->size) || + (sp >= dp && sp < dp + dst_p->shared->size)); + } + else { + assert((dp < sp && dp + dst_p->shared->size <= sp) || + (sp < dp && sp + src_p->shared->size <= dp)); + } +#endif + /* + * Put the data in little endian order so our loops aren't so + * complicated. We'll do all the conversion stuff assuming + * little endian and then we'll fix the order at the end. + */ + if (H5T_ORDER_BE == src.order) { + half_size = src_p->shared->size / 2; + for (i = 0; i < half_size; i++) { + tmp1 = s[src_p->shared->size - (i + 1)]; + s[src_p->shared->size - (i + 1)] = s[i]; + s[i] = tmp1; + } + } + else if (H5T_ORDER_VAX == src.order) { + tsize = src_p->shared->size; + assert(0 == tsize % 2); + + for (i = 0; i < tsize; i += 4) { + tmp1 = s[i]; + tmp2 = s[i + 1]; + + s[i] = s[(tsize - 2) - i]; + s[i + 1] = s[(tsize - 1) - i]; + + s[(tsize - 2) - i] = tmp1; + s[(tsize - 1) - i] = tmp2; + } + } + + /*zero-set all destination bits*/ + H5T__bit_set(d, dst.offset, dst.prec, false); + + /* + * Find the sign bit value of the source. + */ + sign = (hssize_t)H5T__bit_get_d(s, src.u.f.sign, (size_t)1); + + /* + * Check for special cases: +0, -0, +Inf, -Inf, NaN + */ + if (H5T__bit_find(s, src.u.f.mpos, src.u.f.msize, H5T_BIT_LSB, true) < 0) { + if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, true) < 0) { + /* +0 or -0 */ + /* Set all bits to zero */ + goto padding; + } + else if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { + /* +Infinity or -Infinity */ + if (sign) { /* -Infinity */ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_NINF, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + if (H5T_SGN_2 == dst.u.i.sign) + H5T__bit_set(d, dst.prec - 1, (size_t)1, true); + } + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + } + else { /* +Infinity */ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_PINF, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + if (H5T_SGN_NONE == dst.u.i.sign) + H5T__bit_set(d, dst.offset, dst.prec, true); + else if (H5T_SGN_2 == dst.u.i.sign) + H5T__bit_set(d, dst.offset, dst.prec - 1, true); + } + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + } + goto padding; + } + } + else if (H5T_NORM_NONE == src.u.f.norm && + H5T__bit_find(s, src.u.f.mpos, src.u.f.msize - 1, H5T_BIT_LSB, true) < 0 && + H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { + /*This is a special case for the source of no implied mantissa bit. + *If the exponent bits are all 1s and only the 1st bit of mantissa + *is set to 1. It's infinity. The Intel-Linux "long double" is this case.*/ + /* +Infinity or -Infinity */ + if (sign) { /* -Infinity */ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_NINF, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + if (H5T_SGN_2 == dst.u.i.sign) + H5T__bit_set(d, dst.prec - 1, (size_t)1, true); + } + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + } + else { /* +Infinity */ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_PINF, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + if (H5T_SGN_NONE == dst.u.i.sign) + H5T__bit_set(d, dst.offset, dst.prec, true); + else if (H5T_SGN_2 == dst.u.i.sign) + H5T__bit_set(d, dst.offset, dst.prec - 1, true); + } + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + } + goto padding; + } + else if (H5T__bit_find(s, src.u.f.epos, src.u.f.esize, H5T_BIT_LSB, false) < 0) { + /* NaN */ + if (conv_ctx->u.conv.cb_struct.func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_NAN, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, + src_rev, d, conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + /*Just set all bits to zero.*/ + goto padding; + } + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); + + goto padding; + } + + /* + * Get the exponent as an unsigned quantity from the section of + * the source bit field where it's located. Not expecting + * exponent to be greater than the maximal value of hssize_t. + */ + expo = (hssize_t)H5T__bit_get_d(s, src.u.f.epos, src.u.f.esize); + + /* + * Calculate the true source exponent by adjusting according to + * the source exponent bias. + */ + if (0 == expo || H5T_NORM_NONE == src.u.f.norm) { + expo -= (hssize_t)(src.u.f.ebias - 1); + } + else if (H5T_NORM_IMPLIED == src.u.f.norm) { + expo -= (hssize_t)src.u.f.ebias; + } + else { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "normalization method not implemented yet"); + } + + /* + * Get the mantissa as bit vector from the section of + * the source bit field where it's located. + * Keep the little-endian order in the buffer. + * A sequence 0x01020304 will be like in the buffer, + * 04 03 02 01 + * | | | | + * V V V V + * buf[0] buf[1] buf[2] buf[3] + */ + H5T__bit_copy(int_buf, (size_t)0, s, src.u.f.mpos, src.u.f.msize); + + /* + * Restore the implicit bit for mantissa if it's implied. + * Equivalent to mantissa |= (hsize_t)1<u.conv.cb_struct.func) + truncated = true; + + if (H5T_SGN_NONE == dst.u.i.sign) { /*destination is unsigned*/ + /* + * Destination is unsigned. Library's default way: If the source value + * is greater than the maximal destination value then it overflows, the + * destination will be set to the maximum possible value. When the + * source is negative, underflow happens. Set the destination to be + * zero(do nothing). If user's exception handler is set, call it and + * let user handle it. + */ + if (sign) { /*source is negative*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + } + } + else { /*source is positive*/ + if (new_msb_pos >= (ssize_t)dst.prec) { + /*overflow*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) + H5T__bit_set(d, dst.offset, dst.prec, true); + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + } + else { + if (truncated && conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + /*copy source value into it if case is ignored by user handler*/ + if (new_msb_pos >= 0) + H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, (size_t)new_msb_pos + 1); + } + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + } + } + } + else if (H5T_SGN_2 == dst.u.i.sign) { /*Destination is signed*/ + if (sign) { /*source is negative*/ + if ((new_msb_pos >= 0) && ((size_t)new_msb_pos < dst.prec - 1)) { + if (truncated && conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { /*If this case ignored by user handler*/ + /*Convert to integer representation. Equivalent to ~(value - 1).*/ + H5T__bit_dec(int_buf, (size_t)0, dst.prec); + H5T__bit_neg(int_buf, (size_t)0, dst.prec); + + /*copy source value into destination*/ + H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, dst.prec - 1); + H5T__bit_set(d, (dst.offset + dst.prec - 1), (size_t)1, true); + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + } + else { + /* if underflows and no callback, do nothing except turn on + * the sign bit because 0x80...00 is the biggest negative value. + */ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) + H5T__bit_set(d, (dst.offset + dst.prec - 1), (size_t)1, true); + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + } + } + else { /*source is positive*/ + if (new_msb_pos >= (ssize_t)dst.prec - 1) { + /*overflow*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) + H5T__bit_set(d, dst.offset, dst.prec - 1, true); + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + } + else if (new_msb_pos < (ssize_t)dst.prec - 1) { + if (truncated && conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + /*copy source value into it if case is ignored by user handler*/ + if (new_msb_pos >= 0) + H5T__bit_copy(d, dst.offset, int_buf, (size_t)0, (size_t)new_msb_pos + 1); + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) { + /*No need to reverse the order of destination because user handles it*/ + reverse = false; + goto next; + } + } + } + } + +padding: + /* + * Set padding areas in destination. + */ + if (dst.offset > 0) { + assert(H5T_PAD_ZERO == dst.lsb_pad || H5T_PAD_ONE == dst.lsb_pad); + H5T__bit_set(d, (size_t)0, dst.offset, (bool)(H5T_PAD_ONE == dst.lsb_pad)); + } + if (dst.offset + dst.prec != 8 * dst_p->shared->size) { + assert(H5T_PAD_ZERO == dst.msb_pad || H5T_PAD_ONE == dst.msb_pad); + H5T__bit_set(d, dst.offset + dst.prec, 8 * dst_p->shared->size - (dst.offset + dst.prec), + (bool)(H5T_PAD_ONE == dst.msb_pad)); + } + + /* + * Put the destination in the correct byte order. See note at + * beginning of loop. + */ + if (H5T_ORDER_BE == dst.order && reverse) { + half_size = dst_p->shared->size / 2; + for (i = 0; i < half_size; i++) { + tmp1 = d[dst_p->shared->size - (i + 1)]; + d[dst_p->shared->size - (i + 1)] = d[i]; + d[i] = tmp1; + } + } + +next: + /* + * If we had used a temporary buffer for the destination then we + * should copy the value to the true destination buffer. + */ + if (d == dbuf) + H5MM_memcpy(dp, d, dst_p->shared->size); + if (buf_stride) { + sp += direction * (ssize_t)buf_stride; + dp += direction * (ssize_t)buf_stride; + } + else { + sp += direction * (ssize_t)src_p->shared->size; + dp += direction * (ssize_t)dst_p->shared->size; + } + + memset(int_buf, 0, buf_size); + } + + break; + + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + if (int_buf) + H5MM_xfree(int_buf); + if (src_rev) + H5MM_free(src_rev); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_f_i() */ + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_schar + * + * Purpose: Converts `_Float16' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT16, SCHAR, H5__Float16, signed char, SCHAR_MIN, SCHAR_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_uchar + * + * Purpose: Converts `_Float16' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT16, UCHAR, H5__Float16, unsigned char, 0, UCHAR_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_short + * + * Purpose: Converts `_Float16' to `signed short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT16, SHORT, H5__Float16, short, SHRT_MIN, SHRT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_ushort + * + * Purpose: Converts `_Float16' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fX(FLOAT16, USHORT, H5__Float16, unsigned short, 0, USHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_int + * + * Purpose: Converts `_Float16' to `signed int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fX(FLOAT16, INT, H5__Float16, int, INT_MIN, INT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_uint + * + * Purpose: Converts `_Float16' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fX(FLOAT16, UINT, H5__Float16, unsigned int, 0, UINT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_long + * + * Purpose: Converts `_Float16' to `signed long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fX(FLOAT16, LONG, H5__Float16, long, LONG_MIN, LONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_ulong + * + * Purpose: Converts `_Float16' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fX(FLOAT16, ULONG, H5__Float16, unsigned long, 0, ULONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_llong + * + * Purpose: Converts `_Float16' to `signed long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fX(FLOAT16, LLONG, H5__Float16, long long, LLONG_MIN, LLONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_ullong + * + * Purpose: Converts `_Float16' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fX(FLOAT16, ULLONG, H5__Float16, unsigned long long, 0, ULLONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_float + * + * Purpose: Converts `_Float16' to `float' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fF(FLOAT16, FLOAT, H5__Float16, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_double + * + * Purpose: Converts `_Float16' to `double' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fF(FLOAT16, DOUBLE, H5__Float16, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv__Float16_ldouble + * + * Purpose: Converts `_Float16' to `long double' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv__Float16_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fF(FLOAT16, LDOUBLE, H5__Float16, long double, -, -); +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_schar + * + * Purpose: Convert native float to native signed char using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, SCHAR, float, signed char, SCHAR_MIN, SCHAR_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_uchar + * + * Purpose: Convert native float to native unsigned char using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, UCHAR, float, unsigned char, 0, UCHAR_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_short + * + * Purpose: Convert native float to native short using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, SHORT, float, short, SHRT_MIN, SHRT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_ushort + * + * Purpose: Convert native float to native unsigned short using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, USHORT, float, unsigned short, 0, USHRT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_int + * + * Purpose: Convert native float to native int using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, INT, float, int, INT_MIN, INT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_uint + * + * Purpose: Convert native float to native unsigned int using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, UINT, float, unsigned int, 0, UINT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_long + * + * Purpose: Convert native float to native long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, LONG, float, long, LONG_MIN, LONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_ulong + * + * Purpose: Convert native float to native unsigned long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, ULONG, float, unsigned long, 0, ULONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_llong + * + * Purpose: Convert native float to native long long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, LLONG, float, long long, LLONG_MIN, LLONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_ullong + * + * Purpose: Convert native float to native unsigned long long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(FLOAT, ULLONG, float, unsigned long long, 0, ULLONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_float__Float16 + * + * Purpose: Convert native float to native _Float16 using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Ff(FLOAT, FLOAT16, float, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_double + * + * Purpose: Convert native `float' to native `double' using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fF(FLOAT, DOUBLE, float, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_float_ldouble + * + * Purpose: Convert native `float' to native `long double' using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_float_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fF(FLOAT, LDOUBLE, float, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_schar + * + * Purpose: Convert native double to native signed char using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, SCHAR, double, signed char, SCHAR_MIN, SCHAR_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_uchar + * + * Purpose: Convert native double to native unsigned char using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, UCHAR, double, unsigned char, 0, UCHAR_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_short + * + * Purpose: Convert native double to native short using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, SHORT, double, short, SHRT_MIN, SHRT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_ushort + * + * Purpose: Convert native double to native unsigned short using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, USHORT, double, unsigned short, 0, USHRT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_int + * + * Purpose: Convert native double to native int using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, INT, double, int, INT_MIN, INT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_uint + * + * Purpose: Convert native double to native unsigned int using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, UINT, double, unsigned int, 0, UINT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_long + * + * Purpose: Convert native double to native long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, LONG, double, long, LONG_MIN, LONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_ulong + * + * Purpose: Convert native double to native unsigned long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, ULONG, double, unsigned long, 0, ULONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_llong + * + * Purpose: Convert native double to native long long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, LLONG, double, long long, LLONG_MIN, LLONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_ullong + * + * Purpose: Convert native double to native unsigned long long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(DOUBLE, ULLONG, double, unsigned long long, 0, ULLONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_double__Float16 + * + * Purpose: Convert native double to native _Float16 using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Ff(DOUBLE, FLOAT16, double, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_float + * + * Purpose: Convert native `double' to native `float' using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ff(DOUBLE, FLOAT, double, float, -FLT_MAX, FLT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_double_ldouble + * + * Purpose: Convert native `double' to native `long double' using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_double_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_fF(DOUBLE, LDOUBLE, double, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_schar + * + * Purpose: Convert native long double to native signed char using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, SCHAR, long double, signed char, SCHAR_MIN, SCHAR_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_uchar + * + * Purpose: Convert native long double to native unsigned char using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, UCHAR, long double, unsigned char, 0, UCHAR_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_short + * + * Purpose: Convert native long double to native short using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, SHORT, long double, short, SHRT_MIN, SHRT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_ushort + * + * Purpose: Convert native long double to native unsigned short using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, USHORT, long double, unsigned short, 0, USHRT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_int + * + * Purpose: Convert native long double to native int using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, INT, long double, int, INT_MIN, INT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_uint + * + * Purpose: Convert native long double to native unsigned int using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, UINT, long double, unsigned int, 0, UINT_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_long + * + * Purpose: Convert native long double to native long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, LONG, long double, long, LONG_MIN, LONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_ulong + * + * Purpose: Convert native long double to native unsigned long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, ULONG, long double, unsigned long, 0, ULONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_llong + * + * Purpose: Convert native long double to native long long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +#ifdef H5T_CONV_INTERNAL_LDOUBLE_LLONG +herr_t +H5T__conv_ldouble_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, LLONG, long double, long long, LLONG_MIN, LLONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} +#endif /*H5T_CONV_INTERNAL_LDOUBLE_LLONG*/ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_ullong + * + * Purpose: Convert native long double to native unsigned long long using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +#ifdef H5T_CONV_INTERNAL_LDOUBLE_ULLONG +herr_t +H5T__conv_ldouble_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5_GCC_CLANG_DIAG_OFF("float-equal") + H5T_CONV_Fx(LDOUBLE, ULLONG, long double, unsigned long long, 0, ULLONG_MAX); + H5_GCC_CLANG_DIAG_ON("float-equal") +} +#endif /*H5T_CONV_INTERNAL_LDOUBLE_ULLONG*/ + +#ifdef H5_HAVE__FLOAT16 +#ifdef H5T_CONV_INTERNAL_LDOUBLE_FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble__Float16 + * + * Purpose: Convert native long double to native _Float16 using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Ff(LDOUBLE, FLOAT16, long double, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_float + * + * Purpose: Convert native `long double' to native `float' using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ff(LDOUBLE, FLOAT, long double, float, -FLT_MAX, FLT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ldouble_double + * + * Purpose: Convert native `long double' to native `double' using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ldouble_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ff(LDOUBLE, DOUBLE, long double, double, -DBL_MAX, DBL_MAX); +} diff --git a/src/H5Tconv_float.h b/src/H5Tconv_float.h new file mode 100644 index 00000000000..df349d26874 --- /dev/null +++ b/src/H5Tconv_float.h @@ -0,0 +1,215 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_float_H +#define H5Tconv_float_H + +/* Private headers needed by this file */ +#include "H5Tpkg.h" + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/****************************************/ +/* Soft (emulated) conversion functions */ +/****************************************/ + +/* Conversion functions between float datatypes */ +H5_DLL herr_t H5T__conv_f_f(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); + +/* Conversion functions from float datatype to another datatype class */ +H5_DLL herr_t H5T__conv_f_i(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); + +/*********************************************/ +/* Hard (compiler cast) conversion functions */ +/*********************************************/ + +/* Conversion functions for '_Float16' */ +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv__Float16_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv__Float16_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif + +/* Conversion functions for 'float' */ +H5_DLL herr_t H5T__conv_float_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_float__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_float_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_float_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'double' */ +H5_DLL herr_t H5T__conv_double_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_double__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_double_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_double_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'long double' */ +H5_DLL herr_t H5T__conv_ldouble_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +#ifdef H5T_CONV_INTERNAL_LDOUBLE_FLOAT16 +H5_DLL herr_t H5T__conv_ldouble__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +#endif +H5_DLL herr_t H5T__conv_ldouble_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ldouble_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +#endif /* H5Tconv_float_H */ diff --git a/src/H5Tconv_integer.c b/src/H5Tconv_integer.c new file mode 100644 index 00000000000..9128f777a79 --- /dev/null +++ b/src/H5Tconv_integer.c @@ -0,0 +1,3181 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Datatype conversion functions for integer datatypes + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5Tconv.h" +#include "H5Tconv_macros.h" +#include "H5Tconv_integer.h" + +/*------------------------------------------------------------------------- + * Function: H5T__conv_i_i + * + * Purpose: Convert one integer type to another. This is the catch-all + * function for integer conversions and is probably not + * particularly fast. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_i_i(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + ssize_t src_delta, dst_delta; /*source & destination stride */ + int direction; /*direction of traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ + size_t olap; /*num overlapping elements */ + uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ + uint8_t *src_rev = NULL; /*order-reversed source buffer */ + uint8_t dbuf[64] = {0}; /*temp destination buffer */ + size_t first; + ssize_t sfirst; /*a signed version of `first' */ + size_t i; /*Local index variables */ + H5T_conv_ret_t except_ret; /*return of callback function */ + bool reverse; /*if reverse the order of destination */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); + if (H5T_ORDER_LE != dst->shared->u.atomic.order && H5T_ORDER_BE != dst->shared->u.atomic.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); + if (dst->shared->size > sizeof dbuf) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + + /* + * Do we process the values from beginning to end or vice versa? Also, + * how many of the elements have the source and destination areas + * overlapping? + */ + if (src->shared->size == dst->shared->size || buf_stride) { + sp = dp = (uint8_t *)buf; + direction = 1; + olap = nelmts; + } + else if (src->shared->size >= dst->shared->size) { + double olap_d = + ceil((double)(dst->shared->size) / (double)(src->shared->size - dst->shared->size)); + + olap = (size_t)olap_d; + sp = dp = (uint8_t *)buf; + direction = 1; + } + else { + double olap_d = + ceil((double)(src->shared->size) / (double)(dst->shared->size - src->shared->size)); + olap = (size_t)olap_d; + sp = (uint8_t *)buf + (nelmts - 1) * src->shared->size; + dp = (uint8_t *)buf + (nelmts - 1) * dst->shared->size; + direction = -1; + } + + /* + * Direction & size of buffer traversal. + */ + H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); + H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); + H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); + src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src->shared->size); + dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst->shared->size); + + /* Allocate space for order-reversed source buffer */ + src_rev = (uint8_t *)H5MM_calloc(src->shared->size); + + /* The conversion loop */ + for (elmtno = 0; elmtno < nelmts; elmtno++) { + + /* + * If the source and destination buffers overlap then use a + * temporary buffer for the destination. + */ + if (direction > 0) { + s = sp; + d = elmtno < olap ? dbuf : dp; + } + else { + s = sp; + d = elmtno + olap >= nelmts ? dbuf : dp; + } +#ifndef NDEBUG + /* I don't quite trust the overlap calculations yet */ + if (d == dbuf) { + assert((dp >= sp && dp < sp + src->shared->size) || + (sp >= dp && sp < dp + dst->shared->size)); + } + else { + assert((dp < sp && dp + dst->shared->size <= sp) || + (sp < dp && sp + src->shared->size <= dp)); + } +#endif + + /* + * Put the data in little endian order so our loops aren't so + * complicated. We'll do all the conversion stuff assuming + * little endian and then we'll fix the order at the end. + */ + if (H5T_ORDER_BE == src->shared->u.atomic.order) { + half_size = src->shared->size / 2; + for (i = 0; i < half_size; i++) { + uint8_t tmp = s[src->shared->size - (i + 1)]; + s[src->shared->size - (i + 1)] = s[i]; + s[i] = tmp; + } + } + + /* + * What is the bit number for the msb bit of S which is set? The + * bit number is relative to the significant part of the number. + */ + sfirst = H5T__bit_find(s, src->shared->u.atomic.offset, src->shared->u.atomic.prec, + H5T_BIT_MSB, true); + first = (size_t)sfirst; + + /* Set these variables to default */ + except_ret = H5T_CONV_UNHANDLED; + reverse = true; + + if (sfirst < 0) { + /* + * The source has no bits set and must therefore be zero. + * Set the destination to zero. + */ + H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, false); + } + else if (H5T_SGN_NONE == src->shared->u.atomic.u.i.sign && + H5T_SGN_NONE == dst->shared->u.atomic.u.i.sign) { + /* + * Source and destination are both unsigned, but if the + * source has more precision bits than the destination then + * it's possible to overflow. When overflow occurs the + * destination will be set to the maximum possible value. + */ + if (src->shared->u.atomic.prec <= dst->shared->u.atomic.prec) { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + src->shared->u.atomic.prec); + H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, + dst->shared->u.atomic.prec - src->shared->u.atomic.prec, false); + } + else if (first >= dst->shared->u.atomic.prec) { + /*overflow*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, true); + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) + /*Don't reverse because user handles it already*/ + reverse = false; + } + else { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + dst->shared->u.atomic.prec); + } + } + else if (H5T_SGN_2 == src->shared->u.atomic.u.i.sign && + H5T_SGN_NONE == dst->shared->u.atomic.u.i.sign) { + /* + * If the source is signed and the destination isn't then we + * can have overflow if the source contains more bits than + * the destination (destination is set to the maximum + * possible value) or overflow if the source is negative + * (destination is set to zero). + */ + if (first + 1 == src->shared->u.atomic.prec) { + /*overflow - source is negative*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, false); + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) + /*Don't reverse because user handles it already*/ + reverse = false; + } + else if (src->shared->u.atomic.prec < dst->shared->u.atomic.prec) { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + src->shared->u.atomic.prec - 1); + H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec - 1, + (dst->shared->u.atomic.prec - src->shared->u.atomic.prec) + 1, false); + } + else if (first >= dst->shared->u.atomic.prec) { + /*overflow - source is positive*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) + H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, true); + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) + /*Don't reverse because user handles it already*/ + reverse = false; + } + else { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + dst->shared->u.atomic.prec); + } + } + else if (H5T_SGN_NONE == src->shared->u.atomic.u.i.sign && + H5T_SGN_2 == dst->shared->u.atomic.u.i.sign) { + /* + * If the source is not signed but the destination is then + * overflow can occur in which case the destination is set to + * the largest possible value (all bits set except the msb). + */ + if (first + 1 >= dst->shared->u.atomic.prec) { + /*overflow*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec - 1, + true); + H5T__bit_set(d, (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec - 1), + (size_t)1, false); + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) + /*Don't reverse because user handles it already*/ + reverse = false; + } + else if (src->shared->u.atomic.prec < dst->shared->u.atomic.prec) { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + src->shared->u.atomic.prec); + H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, + dst->shared->u.atomic.prec - src->shared->u.atomic.prec, false); + } + else { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + dst->shared->u.atomic.prec); + } + } + else if (first + 1 == src->shared->u.atomic.prec) { + /* + * Both the source and the destination are signed and the + * source value is negative. We could experience overflow + * if the destination isn't wide enough in which case the + * destination is set to a negative number with the largest + * possible magnitude. + */ + ssize_t sfz = H5T__bit_find(s, src->shared->u.atomic.offset, + src->shared->u.atomic.prec - 1, H5T_BIT_MSB, false); + size_t fz = (size_t)sfz; + + if (sfz >= 0 && fz + 1 >= dst->shared->u.atomic.prec) { + /*overflow*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec - 1, + false); + H5T__bit_set(d, (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec - 1), + (size_t)1, true); + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) + /*Don't reverse because user handles it already*/ + reverse = false; + } + else if (src->shared->u.atomic.prec < dst->shared->u.atomic.prec) { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + src->shared->u.atomic.prec); + H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, + dst->shared->u.atomic.prec - src->shared->u.atomic.prec, true); + } + else { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + dst->shared->u.atomic.prec); + } + } + else { + /* + * Source and destination are both signed but the source + * value is positive. We could have an overflow in which + * case the destination is set to the largest possible + * positive value. + */ + if (first + 1 >= dst->shared->u.atomic.prec) { + /*overflow*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*If user's exception handler is present, use it*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, + conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_UNHANDLED) { + H5T__bit_set(d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec - 1, + true); + H5T__bit_set(d, (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec - 1), + (size_t)1, false); + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) + /*Don't reverse because user handles it already*/ + reverse = false; + } + else if (src->shared->u.atomic.prec < dst->shared->u.atomic.prec) { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + src->shared->u.atomic.prec); + H5T__bit_set(d, dst->shared->u.atomic.offset + src->shared->u.atomic.prec, + dst->shared->u.atomic.prec - src->shared->u.atomic.prec, false); + } + else { + H5T__bit_copy(d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, + dst->shared->u.atomic.prec); + } + } + + /* + * Set padding areas in destination. + */ + if (dst->shared->u.atomic.offset > 0) { + assert(H5T_PAD_ZERO == dst->shared->u.atomic.lsb_pad || + H5T_PAD_ONE == dst->shared->u.atomic.lsb_pad); + H5T__bit_set(d, (size_t)0, dst->shared->u.atomic.offset, + (bool)(H5T_PAD_ONE == dst->shared->u.atomic.lsb_pad)); + } + if (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec != 8 * dst->shared->size) { + assert(H5T_PAD_ZERO == dst->shared->u.atomic.msb_pad || + H5T_PAD_ONE == dst->shared->u.atomic.msb_pad); + H5T__bit_set(d, dst->shared->u.atomic.offset + dst->shared->u.atomic.prec, + 8 * dst->shared->size - + (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec), + (bool)(H5T_PAD_ONE == dst->shared->u.atomic.msb_pad)); + } + + /* + * Put the destination in the correct byte order. See note at + * beginning of loop. + */ + if (H5T_ORDER_BE == dst->shared->u.atomic.order && reverse) { + half_size = dst->shared->size / 2; + for (i = 0; i < half_size; i++) { + uint8_t tmp = d[dst->shared->size - (i + 1)]; + d[dst->shared->size - (i + 1)] = d[i]; + d[i] = tmp; + } + } + + /* + * If we had used a temporary buffer for the destination then we + * should copy the value to the true destination buffer. + */ + if (d == dbuf) + H5MM_memcpy(dp, d, dst->shared->size); + + /* Advance source & destination pointers by delta amounts */ + sp += src_delta; + dp += dst_delta; + } /* end for */ + + break; + + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + if (src_rev) + H5MM_free(src_rev); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_i_i() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_i_f + * + * Purpose: Convert one integer type to a floating-point type. This is + * the catch-all function for integer-float conversions and + * is probably not particularly fast. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_i_f(const H5T_t *src_p, const H5T_t *dst_p, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + /* Traversal-related variables */ + H5T_atomic_t src; /*atomic source info */ + H5T_atomic_t dst; /*atomic destination info */ + int direction; /*forward or backward traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ + size_t tsize; /*type size for swapping bytes */ + size_t olap; /*num overlapping elements */ + uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ + uint8_t *src_rev = NULL; /*order-reversed source buffer */ + uint8_t dbuf[64] = {0}; /*temp destination buffer */ + uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ + + /* Conversion-related variables */ + hsize_t expo; /*destination exponent */ + hsize_t expo_max; /*maximal possible exponent value */ + size_t sign; /*source sign bit value */ + bool is_max_neg; /*source is maximal negative value*/ + bool do_round; /*whether there is roundup */ + uint8_t *int_buf = NULL; /*buffer for temporary value */ + size_t buf_size; /*buffer size for temporary value */ + size_t i; /*miscellaneous counters */ + size_t first; /*first bit(MSB) in an integer */ + ssize_t sfirst; /*a signed version of `first' */ + H5T_conv_ret_t except_ret; /*return of callback function */ + bool reverse; /*if reverse the order of destination */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + if (NULL == src_p || NULL == dst_p) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + src = src_p->shared->u.atomic; + dst = dst_p->shared->u.atomic; + if (H5T_ORDER_LE != dst.order && H5T_ORDER_BE != dst.order && H5T_ORDER_VAX != dst.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); + if (dst_p->shared->size > sizeof(dbuf)) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); + if (8 * sizeof(expo) - 1 < src.u.f.esize) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + if (NULL == src_p || NULL == dst_p) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + + src = src_p->shared->u.atomic; + dst = dst_p->shared->u.atomic; + + /* + * Do we process the values from beginning to end or vice versa? Also, + * how many of the elements have the source and destination areas + * overlapping? + */ + if (src_p->shared->size == dst_p->shared->size || buf_stride) { + sp = dp = (uint8_t *)buf; + direction = 1; + olap = nelmts; + } + else if (src_p->shared->size >= dst_p->shared->size) { + double olap_d = + ceil((double)(dst_p->shared->size) / (double)(src_p->shared->size - dst_p->shared->size)); + olap = (size_t)olap_d; + sp = dp = (uint8_t *)buf; + direction = 1; + } + else { + double olap_d = + ceil((double)(src_p->shared->size) / (double)(dst_p->shared->size - src_p->shared->size)); + olap = (size_t)olap_d; + sp = (uint8_t *)buf + (nelmts - 1) * src_p->shared->size; + dp = (uint8_t *)buf + (nelmts - 1) * dst_p->shared->size; + direction = -1; + } + + /* Allocate enough space for the buffer holding temporary + * converted value + */ + buf_size = ((src.prec > dst.u.f.msize ? src.prec : dst.u.f.msize) + 7) / 8; + int_buf = (uint8_t *)H5MM_calloc(buf_size); + + /* Allocate space for order-reversed source buffer */ + src_rev = (uint8_t *)H5MM_calloc(src_p->shared->size); + + /* The conversion loop */ + for (elmtno = 0; elmtno < nelmts; elmtno++) { + /* Set these variables to default */ + except_ret = H5T_CONV_UNHANDLED; + reverse = true; + + /* Make sure these variables are reset to 0. */ + sign = 0; /*source sign bit value */ + is_max_neg = 0; /*source is maximal negative value*/ + do_round = 0; /*whether there is roundup */ + sfirst = 0; + + /* + * If the source and destination buffers overlap then use a + * temporary buffer for the destination. + */ + if (direction > 0) { + s = sp; + d = elmtno < olap ? dbuf : dp; + } + else { + s = sp; + d = elmtno + olap >= nelmts ? dbuf : dp; + } +#ifndef NDEBUG + /* I don't quite trust the overlap calculations yet */ + if (d == dbuf) { + assert((dp >= sp && dp < sp + src_p->shared->size) || + (sp >= dp && sp < dp + dst_p->shared->size)); + } + else { + assert((dp < sp && dp + dst_p->shared->size <= sp) || + (sp < dp && sp + src_p->shared->size <= dp)); + } +#endif + + /* Put the data in little endian order so our loops aren't so + * complicated. We'll do all the conversion stuff assuming + * little endian and then we'll fix the order at the end. + */ + if (H5T_ORDER_BE == src.order) { + half_size = src_p->shared->size / 2; + for (i = 0; i < half_size; i++) { + tmp1 = s[src_p->shared->size - (i + 1)]; + s[src_p->shared->size - (i + 1)] = s[i]; + s[i] = tmp1; + } + } + + /* Zero-set all destination bits*/ + H5T__bit_set(d, dst.offset, dst.prec, false); + + /* Copy source into a temporary buffer */ + H5T__bit_copy(int_buf, (size_t)0, s, src.offset, src.prec); + + /* Find the sign bit value of the source */ + if (H5T_SGN_2 == src.u.i.sign) + sign = (size_t)H5T__bit_get_d(int_buf, src.prec - 1, (size_t)1); + + /* What is the bit position(starting from 0 as first one) for the most significant + * bit(MSB) of S which is set? + */ + if (H5T_SGN_2 == src.u.i.sign) { + sfirst = H5T__bit_find(int_buf, (size_t)0, src.prec - 1, H5T_BIT_MSB, true); + if (sign && sfirst < 0) + /* The case 0x80...00, which is negative with maximal value */ + is_max_neg = 1; + } + else if (H5T_SGN_NONE == src.u.i.sign) + sfirst = H5T__bit_find(int_buf, (size_t)0, src.prec, H5T_BIT_MSB, true); + + /* Handle special cases here. Integer is zero */ + if (!sign && sfirst < 0) + goto padding; + + /* Convert source integer if it's negative */ + if (H5T_SGN_2 == src.u.i.sign && sign) { + if (!is_max_neg) { + /* Equivalent to ~(i - 1) */ + H5T__bit_dec(int_buf, (size_t)0, buf_size * 8); + H5T__bit_neg(int_buf, (size_t)0, buf_size * 8); + sfirst = H5T__bit_find(int_buf, (size_t)0, src.prec - 1, H5T_BIT_MSB, true); + } + else { + /* If it's maximal negative number 0x80...000, treat it as if it overflowed + * (create a carry) to help conversion. i.e. a character type number 0x80 + * is treated as 0x100. + */ + sfirst = (ssize_t)(src.prec - 1); + is_max_neg = 0; + } + if (sfirst < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "zero bit not found"); + + /* Sign bit has been negated if bit vector isn't 0x80...00. Set all bits in front of + * sign bit to 0 in the temporary buffer because they're all negated from the previous + * step. + */ + H5T__bit_set(int_buf, src.prec, (buf_size * 8) - src.prec, 0); + + /* Set sign bit in destination */ + H5T__bit_set_d(d, dst.u.f.sign, (size_t)1, (hsize_t)sign); + } /* end if */ + + first = (size_t)sfirst; + + /* Calculate the true destination exponent by adjusting according to + * the destination exponent bias. Implied and non-implied normalization + * should be the same. + */ + if (H5T_NORM_NONE == dst.u.f.norm || H5T_NORM_IMPLIED == dst.u.f.norm) { + expo = first + dst.u.f.ebias; + } + else { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "normalization method not implemented yet"); + } + + /* Handle mantissa part here */ + if (H5T_NORM_IMPLIED == dst.u.f.norm) { + /* Imply first bit */ + H5T__bit_set(int_buf, first, (size_t)1, 0); + } + else if (H5T_NORM_NONE == dst.u.f.norm) { + first++; + } + + /* Roundup for mantissa */ + if (first > dst.u.f.msize) { + /* If the bit sequence is bigger than the mantissa part, there'll be some + * precision loss. Let user's handler deal with the case if it's present + */ + if (conv_ctx->u.conv.cb_struct.func) { + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); /*reverse order first*/ + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_PRECISION, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, conv_ctx->u.conv.cb_struct.user_data); + } + + if (except_ret == H5T_CONV_HANDLED) { + reverse = false; + goto padding; + } + else if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); + + /* If user's exception handler does deal with it, we do it by dropping off the + * extra bits at the end and do rounding. If we have .50...0(decimal) after radix + * point, we do roundup when the least significant digit before radix is odd, we do + * rounddown if it's even. + */ + + /* Check 1st dropoff bit, see if it's set. */ + if (H5T__bit_get_d(int_buf, ((first - dst.u.f.msize) - 1), (size_t)1)) { + /* Check all bits after 1st dropoff bit, see if any of them is set. */ + if (((first - dst.u.f.msize) - 1) > 0 && + H5T__bit_get_d(int_buf, (size_t)0, ((first - dst.u.f.msize) - 1))) + do_round = 1; + else { /* The .50...0 case */ + /* Check if the least significant bit is odd. */ + if (H5T__bit_get_d(int_buf, (first - dst.u.f.msize), (size_t)1)) + do_round = 1; + } + } + + /* Right shift to drop off extra bits */ + H5T__bit_shift(int_buf, (ssize_t)(dst.u.f.msize - first), (size_t)0, buf_size * 8); + + if (do_round) { + H5T__bit_inc(int_buf, (size_t)0, buf_size * 8); + do_round = 0; + + /* If integer is like 0x0ff...fff and we need to round up the + * last f, we get 0x100...000. Treat this special case here. + */ + if (H5T__bit_get_d(int_buf, dst.u.f.msize, (size_t)1)) { + if (H5T_NORM_IMPLIED == dst.u.f.norm) { + /* The bit at this 1's position was impled already, so this + * number should be 0x200...000. We need to increment the + * exponent in this case. + */ + expo++; + } + else if (H5T_NORM_NONE == dst.u.f.norm) { + /* Right shift 1 bit to let the carried 1 fit in the mantissa, + * and increment exponent by 1. + */ + H5T__bit_shift(int_buf, (ssize_t)-1, (size_t)0, buf_size * 8); + expo++; + } + } + } + } + else { + /* The bit sequence can fit mantissa part. Left shift to fit in from high-order of + * bit position. */ + H5T__bit_shift(int_buf, (ssize_t)(dst.u.f.msize - first), (size_t)0, dst.u.f.msize); + } + + /* Check if the exponent is too big */ + expo_max = (hsize_t)(pow(2.0, (double)dst.u.f.esize) - 1); + + if (expo > expo_max) { /*overflows*/ + if (conv_ctx->u.conv.cb_struct + .func) { /*user's exception handler. Reverse back source order*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); /*reverse order first*/ + except_ret = (conv_ctx->u.conv.cb_struct.func)( + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, + conv_ctx->u.conv.dst_type_id, src_rev, d, conv_ctx->u.conv.cb_struct.user_data); + + if (except_ret == H5T_CONV_ABORT) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "can't handle conversion exception"); + else if (except_ret == H5T_CONV_HANDLED) { + reverse = false; + goto padding; + } + } + + if (!conv_ctx->u.conv.cb_struct.func || (except_ret == H5T_CONV_UNHANDLED)) { + /*make destination infinity by setting exponent to maximal number and + *mantissa to zero.*/ + expo = expo_max; + memset(int_buf, 0, buf_size); + } + } + + if (except_ret == H5T_CONV_UNHANDLED) { + /* Set exponent in destination */ + H5T__bit_set_d(d, dst.u.f.epos, dst.u.f.esize, expo); + + /* Copy mantissa into destination */ + H5T__bit_copy(d, dst.u.f.mpos, int_buf, (size_t)0, + (buf_size * 8) > dst.u.f.msize ? dst.u.f.msize : buf_size * 8); + } + +padding: + /* + * Set padding areas in destination. + */ + if (dst.offset > 0) { + assert(H5T_PAD_ZERO == dst.lsb_pad || H5T_PAD_ONE == dst.lsb_pad); + H5T__bit_set(d, (size_t)0, dst.offset, (bool)(H5T_PAD_ONE == dst.lsb_pad)); + } + if (dst.offset + dst.prec != 8 * dst_p->shared->size) { + assert(H5T_PAD_ZERO == dst.msb_pad || H5T_PAD_ONE == dst.msb_pad); + H5T__bit_set(d, dst.offset + dst.prec, 8 * dst_p->shared->size - (dst.offset + dst.prec), + (bool)(H5T_PAD_ONE == dst.msb_pad)); + } + + /* + * Put the destination in the correct byte order. See note at + * beginning of loop. + */ + if (H5T_ORDER_BE == dst.order && reverse) { + half_size = dst_p->shared->size / 2; + for (i = 0; i < half_size; i++) { + uint8_t tmp = d[dst_p->shared->size - (i + 1)]; + d[dst_p->shared->size - (i + 1)] = d[i]; + d[i] = tmp; + } + } + else if (H5T_ORDER_VAX == dst.order && reverse) { + tsize = dst_p->shared->size; + assert(0 == tsize % 2); + + for (i = 0; i < tsize; i += 4) { + tmp1 = d[i]; + tmp2 = d[i + 1]; + + d[i] = d[(tsize - 2) - i]; + d[i + 1] = d[(tsize - 1) - i]; + + d[(tsize - 2) - i] = tmp1; + d[(tsize - 1) - i] = tmp2; + } + } + + /* + * If we had used a temporary buffer for the destination then we + * should copy the value to the true destination buffer. + */ + if (d == dbuf) + H5MM_memcpy(dp, d, dst_p->shared->size); + if (buf_stride) { + sp += direction * (ssize_t)buf_stride; + dp += direction * (ssize_t)buf_stride; + } + else { + sp += direction * (ssize_t)src_p->shared->size; + dp += direction * (ssize_t)dst_p->shared->size; + } + + memset(int_buf, 0, buf_size); + } + + break; + + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + if (int_buf) + H5MM_xfree(int_buf); + if (src_rev) + H5MM_free(src_rev); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_i_f() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_uchar + * + * Purpose: Converts `signed char' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_su(SCHAR, UCHAR, signed char, unsigned char, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_short + * + * Purpose: Converts `signed char' to `short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(SCHAR, SHORT, signed char, short, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_ushort + * + * Purpose: Converts `signed char' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(SCHAR, USHORT, signed char, unsigned short, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_int + * + * Purpose: Converts `signed char' to `int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(SCHAR, INT, signed char, int, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_uint + * + * Purpose: Converts `signed char' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(SCHAR, UINT, signed char, unsigned, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_long + * + * Purpose: Converts `signed char' to `long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(SCHAR, LONG, signed char, long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_ulong + * + * Purpose: Converts `signed char' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(SCHAR, ULONG, signed char, unsigned long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_llong + * + * Purpose: Converts `signed char' to `long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(SCHAR, LLONG, signed char, long long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_ullong + * + * Purpose: Converts `signed char' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(SCHAR, ULLONG, signed char, unsigned long long, -, -); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar__Float16 + * + * Purpose: Converts `signed char` to `_Float16` + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(SCHAR, FLOAT16, signed char, H5__Float16, -, -); +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_float + * + * Purpose: Convert native signed char to native float using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(SCHAR, FLOAT, signed char, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_double + * + * Purpose: Convert native signed char to native double using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(SCHAR, DOUBLE, signed char, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_schar_ldouble + * + * Purpose: Convert native signed char to native long double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_schar_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(SCHAR, LDOUBLE, signed char, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_schar + * + * Purpose: Converts `unsigned char' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_us(UCHAR, SCHAR, unsigned char, signed char, -, SCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_short + * + * Purpose: Converts `unsigned char' to `short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(UCHAR, SHORT, unsigned char, short, -, SHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_ushort + * + * Purpose: Converts `unsigned char' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(UCHAR, USHORT, unsigned char, unsigned short, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_int + * + * Purpose: Converts `unsigned char' to `int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(UCHAR, INT, unsigned char, int, -, INT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_uint + * + * Purpose: Converts `unsigned char' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(UCHAR, UINT, unsigned char, unsigned, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_long + * + * Purpose: Converts `unsigned char' to `long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(UCHAR, LONG, unsigned char, long, -, LONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_ulong + * + * Purpose: Converts `unsigned char' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(UCHAR, ULONG, unsigned char, unsigned long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_llong + * + * Purpose: Converts `unsigned char' to `long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(UCHAR, LLONG, unsigned char, long long, -, LLONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_ullong + * + * Purpose: Converts `unsigned char' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(UCHAR, ULLONG, unsigned char, unsigned long long, -, -); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar__Float16 + * + * Purpose: Converts `unsigned char` to `_Float16` + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(UCHAR, FLOAT16, unsigned char, H5__Float16, -, -); +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_float + * + * Purpose: Convert native unsigned char to native float using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(UCHAR, FLOAT, unsigned char, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_double + * + * Purpose: Convert native unsigned char to native double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(UCHAR, DOUBLE, unsigned char, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uchar_ldouble + * + * Purpose: Convert native unsigned char to native long double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uchar_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(UCHAR, LDOUBLE, unsigned char, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_schar + * + * Purpose: Converts `short' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(SHORT, SCHAR, short, signed char, SCHAR_MIN, SCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_uchar + * + * Purpose: Converts `short' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(SHORT, UCHAR, short, unsigned char, -, UCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_ushort + * + * Purpose: Converts `short' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_su(SHORT, USHORT, short, unsigned short, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_int + * + * Purpose: Converts `short' to `int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(SHORT, INT, short, int, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_uint + * + * Purpose: Converts `short' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(SHORT, UINT, short, unsigned, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_long + * + * Purpose: Converts `short' to `long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(SHORT, LONG, short, long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_ulong + * + * Purpose: Converts `short' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(SHORT, ULONG, short, unsigned long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_llong + * + * Purpose: Converts `short' to `long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(SHORT, LLONG, short, long long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_ullong + * + * Purpose: Converts `short' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(SHORT, ULLONG, short, unsigned long long, -, -); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_short__Float16 + * + * Purpose: Converts `short' to `_Float16' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(SHORT, FLOAT16, short, H5__Float16, -, -); +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_float + * + * Purpose: Convert native short to native float using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(SHORT, FLOAT, short, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_double + * + * Purpose: Convert native short to native double using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(SHORT, DOUBLE, short, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_short_ldouble + * + * Purpose: Convert native short to native long double using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_short_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(SHORT, LDOUBLE, short, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_schar + * + * Purpose: Converts `unsigned short' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(USHORT, SCHAR, unsigned short, signed char, -, SCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_uchar + * + * Purpose: Converts `unsigned short' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(USHORT, UCHAR, unsigned short, unsigned char, -, UCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_short + * + * Purpose: Converts `unsigned short' to `short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_us(USHORT, SHORT, unsigned short, short, -, SHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_int + * + * Purpose: Converts `unsigned short' to `int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(USHORT, INT, unsigned short, int, -, INT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_uint + * + * Purpose: Converts `unsigned short' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(USHORT, UINT, unsigned short, unsigned, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_long + * + * Purpose: Converts `unsigned short' to `long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(USHORT, LONG, unsigned short, long, -, LONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_ulong + * + * Purpose: Converts `unsigned short' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(USHORT, ULONG, unsigned short, unsigned long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_llong + * + * Purpose: Converts `unsigned short' to `long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(USHORT, LLONG, unsigned short, long long, -, LLONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_ullong + * + * Purpose: Converts `unsigned short' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(USHORT, ULLONG, unsigned short, unsigned long long, -, -); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort__Float16 + * + * Purpose: Converts `unsigned short' to `_Float16' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Xf(USHORT, FLOAT16, unsigned short, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_float + * + * Purpose: Convert native unsigned short to native float using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(USHORT, FLOAT, unsigned short, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_double + * + * Purpose: Convert native unsigned short to native double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(USHORT, DOUBLE, unsigned short, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ushort_ldouble + * + * Purpose: Convert native unsigned short to native long double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ushort_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(USHORT, LDOUBLE, unsigned short, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_schar + * + * Purpose: Converts `int' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(INT, SCHAR, int, signed char, SCHAR_MIN, SCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_uchar + * + * Purpose: Converts `int' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(INT, UCHAR, int, unsigned char, -, UCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_short + * + * Purpose: Converts `int' to `short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(INT, SHORT, int, short, SHRT_MIN, SHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_ushort + * + * Purpose: Converts `int' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(INT, USHORT, int, unsigned short, -, USHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_uint + * + * Purpose: Converts `int' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_su(INT, UINT, int, unsigned, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_long + * + * Purpose: Converts `int' to `long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(INT, LONG, int, long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_ulong + * + * Purpose: Converts `int' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(INT, LONG, int, unsigned long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_llong + * + * Purpose: Converts `int' to `long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(INT, LLONG, int, long long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_ullong + * + * Purpose: Converts `int' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(INT, ULLONG, int, unsigned long long, -, -); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_int__Float16 + * + * Purpose: Converts `int' to `_Float16' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Xf(INT, FLOAT16, int, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_float + * + * Purpose: Convert native integer to native float using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(INT, FLOAT, int, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_double + * + * Purpose: Convert native integer to native double using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(INT, DOUBLE, int, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_int_ldouble + * + * Purpose: Convert native integer to native long double using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_int_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(INT, LDOUBLE, int, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_schar + * + * Purpose: Converts `unsigned int' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(UINT, SCHAR, unsigned, signed char, -, SCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_uchar + * + * Purpose: Converts `unsigned int' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(UINT, UCHAR, unsigned, unsigned char, -, UCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_short + * + * Purpose: Converts `unsigned int' to `short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(UINT, SHORT, unsigned, short, -, SHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_ushort + * + * Purpose: Converts `unsigned int' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(UINT, USHORT, unsigned, unsigned short, -, USHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_int + * + * Purpose: Converts `unsigned int' to `int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_us(UINT, INT, unsigned, int, -, INT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_long + * + * Purpose: Converts `unsigned int' to `long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(UINT, LONG, unsigned, long, -, LONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_ulong + * + * Purpose: Converts `unsigned int' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(UINT, ULONG, unsigned, unsigned long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_llong + * + * Purpose: Converts `unsigned int' to `long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(UINT, LLONG, unsigned, long long, -, LLONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_ullong + * + * Purpose: Converts `unsigned int' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(UINT, ULLONG, unsigned, unsigned long long, -, -); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint__Float16 + * + * Purpose: Converts `unsigned int' to `_Float16' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Xf(UINT, FLOAT16, unsigned int, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_float + * + * Purpose: Convert native unsigned integer to native float using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(UINT, FLOAT, unsigned int, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_double + * + * Purpose: Convert native unsigned integer to native double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(UINT, DOUBLE, unsigned int, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_uint_ldouble + * + * Purpose: Convert native unsigned integer to native long double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_uint_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(UINT, LDOUBLE, unsigned int, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_schar + * + * Purpose: Converts `long' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(LONG, SCHAR, long, signed char, SCHAR_MIN, SCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_uchar + * + * Purpose: Converts `long' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(LONG, UCHAR, long, unsigned char, -, UCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_short + * + * Purpose: Converts `long' to `short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(LONG, SHORT, long, short, SHRT_MIN, SHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_ushort + * + * Purpose: Converts `long' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(LONG, USHORT, long, unsigned short, -, USHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_int + * + * Purpose: Converts `long' to `int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(LONG, INT, long, int, INT_MIN, INT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_uint + * + * Purpose: Converts `long' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(LONG, UINT, long, unsigned, -, UINT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_ulong + * + * Purpose: Converts `long' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_su(LONG, ULONG, long, unsigned long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_llong + * + * Purpose: Converts `long' to `long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sS(LONG, LLONG, long, long long, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_ullong + * + * Purpose: Converts `long' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_sU(LONG, ULLONG, long, unsigned long long, -, -); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_long__Float16 + * + * Purpose: Converts `long' to `_Float16' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Xf(LONG, FLOAT16, long, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_float + * + * Purpose: Convert native long to native float using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(LONG, FLOAT, long, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_double + * + * Purpose: Convert native long to native double using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(LONG, DOUBLE, long, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_long_ldouble + * + * Purpose: Convert native long to native long double using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_long_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(LONG, LDOUBLE, long, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_schar + * + * Purpose: Converts `unsigned long' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(ULONG, SCHAR, unsigned long, signed char, -, SCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_uchar + * + * Purpose: Converts `unsigned long' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(ULONG, UCHAR, unsigned long, unsigned char, -, UCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_short + * + * Purpose: Converts `unsigned long' to `short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(ULONG, SHORT, unsigned long, short, -, SHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_ushort + * + * Purpose: Converts `unsigned long' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(ULONG, USHORT, unsigned long, unsigned short, -, USHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_int + * + * Purpose: Converts `unsigned long' to `int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(ULONG, INT, unsigned long, int, -, INT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_uint + * + * Purpose: Converts `unsigned long' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(ULONG, UINT, unsigned long, unsigned, -, UINT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_long + * + * Purpose: Converts `unsigned long' to `long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_us(ULONG, LONG, unsigned long, long, -, LONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_llong + * + * Purpose: Converts `unsigned long' to `long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uS(ULONG, LLONG, unsigned long, long long, -, LLONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_ullong + * + * Purpose: Converts `unsigned long' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_uU(ULONG, ULLONG, unsigned long, unsigned long long, -, -); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong__Float16 + * + * Purpose: Converts `unsigned long' to `_Float16' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Xf(ULONG, FLOAT16, unsigned long, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_float + * + * Purpose: Convert native unsigned long to native float using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(ULONG, FLOAT, unsigned long, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_double + * + * Purpose: Convert native unsigned long to native double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(ULONG, DOUBLE, unsigned long, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ulong_ldouble + * + * Purpose: Convert native unsigned long to native long double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ulong_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(ULONG, LDOUBLE, unsigned long, long double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_schar + * + * Purpose: Converts `long long' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(LLONG, SCHAR, long long, signed char, SCHAR_MIN, SCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_uchar + * + * Purpose: Converts `long long' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(LLONG, UCHAR, long long, unsigned char, -, UCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_short + * + * Purpose: Converts `long long' to `short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(LLONG, SHORT, long long, short, SHRT_MIN, SHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_ushort + * + * Purpose: Converts `long long' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(LLONG, USHORT, long long, unsigned short, -, USHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_int + * + * Purpose: Converts `long long' to `int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(LLONG, INT, long long, int, INT_MIN, INT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_uint + * + * Purpose: Converts `long long' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(LLONG, UINT, long long, unsigned, -, UINT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_long + * + * Purpose: Converts `long long' to `long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Ss(LLONG, LONG, long long, long, LONG_MIN, LONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_ulong + * + * Purpose: Converts `long long' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Su(LLONG, ULONG, long long, unsigned long, -, ULONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_ullong + * + * Purpose: Converts `long long' to `unsigned long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_su(LLONG, ULLONG, long long, unsigned long long, -, -); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong__Float16 + * + * Purpose: Converts `long long' to `_Float16' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Xf(LLONG, FLOAT16, long long, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_float + * + * Purpose: Convert native long long to native float using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(LLONG, FLOAT, long long, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_double + * + * Purpose: Convert native long long to native double using hardware. + * This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_llong_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(LLONG, DOUBLE, long long, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_llong_ldouble + * + * Purpose: Convert native long long to native long double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +#ifdef H5T_CONV_INTERNAL_LLONG_LDOUBLE +herr_t +H5T__conv_llong_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(LLONG, LDOUBLE, long long, long double, -, -); +} +#endif /* H5T_CONV_INTERNAL_LLONG_LDOUBLE */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_schar + * + * Purpose: Converts `unsigned long long' to `signed char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(ULLONG, SCHAR, unsigned long long, signed char, -, SCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_uchar + * + * Purpose: Converts `unsigned long long' to `unsigned char' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(ULLONG, UCHAR, unsigned long long, unsigned char, -, UCHAR_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_short + * + * Purpose: Converts `unsigned long long' to `short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(ULLONG, SHORT, unsigned long long, short, -, SHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_ushort + * + * Purpose: Converts `unsigned long long' to `unsigned short' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(ULLONG, USHORT, unsigned long long, unsigned short, -, USHRT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_int + * + * Purpose: Converts `unsigned long long' to `int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(ULLONG, INT, unsigned long long, int, -, INT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_uint + * + * Purpose: Converts `unsigned long long' to `unsigned int' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(ULLONG, UINT, unsigned long long, unsigned, -, UINT_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_long + * + * Purpose: Converts `unsigned long long' to `long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Us(ULLONG, LONG, unsigned long long, long, -, LONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_ulong + * + * Purpose: Converts `unsigned long long' to `unsigned long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_Uu(ULLONG, ULONG, unsigned long long, unsigned long, -, ULONG_MAX); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_llong + * + * Purpose: Converts `unsigned long long' to `long long' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_us(ULLONG, LLONG, unsigned long long, long long, -, LLONG_MAX); +} + +#ifdef H5_HAVE__FLOAT16 +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong__Float16 + * + * Purpose: Converts `unsigned long long' to `_Float16' + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) +{ + /* Suppress warning about non-standard floating-point literal suffix */ + H5_GCC_CLANG_DIAG_OFF("pedantic") + H5T_CONV_Xf(ULLONG, FLOAT16, unsigned long long, H5__Float16, -FLT16_MAX, FLT16_MAX); + H5_GCC_CLANG_DIAG_ON("pedantic") +} +#endif + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_float + * + * Purpose: Convert native unsigned long long to native float using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(ULLONG, FLOAT, unsigned long long, float, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_double + * + * Purpose: Convert native unsigned long long to native double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ullong_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(ULLONG, DOUBLE, unsigned long long, double, -, -); +} + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ullong_ldouble + * + * Purpose: Convert native unsigned long long to native long double using + * hardware. This is a fast special case. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +#ifdef H5T_CONV_INTERNAL_ULLONG_LDOUBLE +herr_t +H5T__conv_ullong_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, + void H5_ATTR_UNUSED *bkg) +{ + H5T_CONV_xF(ULLONG, LDOUBLE, unsigned long long, long double, -, -); +} +#endif /*H5T_CONV_INTERNAL_ULLONG_LDOUBLE*/ diff --git a/src/H5Tconv_integer.h b/src/H5Tconv_integer.h new file mode 100644 index 00000000000..c8eff45a285 --- /dev/null +++ b/src/H5Tconv_integer.h @@ -0,0 +1,471 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_integer_H +#define H5Tconv_integer_H + +/* Private headers needed by this file */ +#include "H5Tpkg.h" + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/****************************************/ +/* Soft (emulated) conversion functions */ +/****************************************/ + +/* Conversion functions between integer datatypes */ +H5_DLL herr_t H5T__conv_i_i(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); + +/* Conversion functions from integer datatype to another datatype class */ +H5_DLL herr_t H5T__conv_i_f(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); + +/*********************************************/ +/* Hard (compiler cast) conversion functions */ +/*********************************************/ + +/* Conversion functions for 'signed char' */ +H5_DLL herr_t H5T__conv_schar_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_schar__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_schar_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_schar_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'unsigned char' */ +H5_DLL herr_t H5T__conv_uchar_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_uchar__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_uchar_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uchar_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'signed short' */ +H5_DLL herr_t H5T__conv_short_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_short__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_short_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_short_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'unsigned short' */ +H5_DLL herr_t H5T__conv_ushort_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_ushort__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_ushort_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ushort_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'signed int' */ +H5_DLL herr_t H5T__conv_int_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_int__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_int_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_int_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'unsigned int' */ +H5_DLL herr_t H5T__conv_uint_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_uint__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_uint_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_uint_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'signed long' */ +H5_DLL herr_t H5T__conv_long_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_long__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_long_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_long_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'unsigned long' */ +H5_DLL herr_t H5T__conv_ulong_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_ulong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_ulong_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ulong_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'signed long long' */ +H5_DLL herr_t H5T__conv_llong_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_llong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_llong_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_llong_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/* Conversion functions for 'unsigned long long' */ +H5_DLL herr_t H5T__conv_ullong_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#ifdef H5_HAVE__FLOAT16 +H5_DLL herr_t H5T__conv_ullong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +#endif +H5_DLL herr_t H5T__conv_ullong_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ullong_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +#endif /* H5Tconv_integer_H */ diff --git a/src/H5Tconv_macros.h b/src/H5Tconv_macros.h new file mode 100644 index 00000000000..c2876670f5e --- /dev/null +++ b/src/H5Tconv_macros.h @@ -0,0 +1,1147 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_macros_H +#define H5Tconv_macros_H + +/* + * Purpose: Contains the macros and infrastructure that make up the atomic + * datatype conversion mechanism + */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error Handling */ +#include "H5Tprivate.h" /* Datatypes */ + +#ifdef H5T_DEBUG + +/* Conversion debugging data for the hardware conversion functions */ +typedef struct H5T_conv_hw_t { + size_t s_aligned; /*number source elements aligned */ + size_t d_aligned; /*number destination elements aligned*/ +} H5T_conv_hw_t; + +#endif + +/* + * These macros are for the bodies of functions that convert buffers of one + * atomic type to another using hardware. + * + * They all start with `H5T_CONV_' and end with two letters that represent the + * source and destination types, respectively. The letters `s' and `S' refer to + * signed integers while the letters `u' and `U' refer to unsigned integers, and + * the letters `f' and `F' refer to floating-point values. + * + * The letter which is capitalized indicates that the corresponding type + * (source or destination) is at least as large as the other type. + * + * Certain conversions may experience overflow conditions which arise when the + * source value has a magnitude that cannot be represented by the destination + * type. + * + * Suffix Description + * ------ ----------- + * sS: Signed integers to signed integers where the destination is + * at least as wide as the source. This case cannot generate + * overflows. + * + * sU: Signed integers to unsigned integers where the destination is + * at least as wide as the source. This case experiences + * overflows when the source value is negative. + * + * uS: Unsigned integers to signed integers where the destination is + * at least as wide as the source. This case can experience + * overflows when the source and destination are the same size. + * + * uU: Unsigned integers to unsigned integers where the destination + * is at least as wide as the source. Overflows are not + * possible in this case. + * + * Ss: Signed integers to signed integers where the source is at + * least as large as the destination. Overflows can occur when + * the destination is narrower than the source. + * + * Su: Signed integers to unsigned integers where the source is at + * least as large as the destination. Overflows occur when the + * source value is negative and can also occur if the + * destination is narrower than the source. + * + * Us: Unsigned integers to signed integers where the source is at + * least as large as the destination. Overflows can occur for + * all sizes. + * + * Uu: Unsigned integers to unsigned integers where the source is at + * least as large as the destination. Overflows can occur if the + * destination is narrower than the source. + * + * su: Conversion from signed integers to unsigned integers where + * the source and destination are the same size. Overflow occurs + * when the source value is negative. + * + * us: Conversion from unsigned integers to signed integers where + * the source and destination are the same size. Overflow + * occurs when the source magnitude is too large for the + * destination. + * + * fF: Floating-point values to floating-point values where the + * destination is at least as wide as the source. This case + * cannot generate overflows. + * + * Ff: Floating-point values to floating-point values the source is at + * least as large as the destination. Overflows can occur when + * the destination is narrower than the source. + * + * xF: Integers to float-point(float or double) values where the destination + * is at least as wide as the source. This case cannot generate + * overflows. + * + * Fx: Float-point(float or double) values to integer where the source is + * at least as wide as the destination. Overflow can occur + * when the source magnitude is too large for the destination. + * + * fX: Floating-point values to integers where the destination is at least + * as wide as the source. This case cannot generate overflows. + * + * Xf: Integers to floating-point values where the source is at least as + * wide as the destination. Overflows can occur when the destination is + * narrower than the source. + * + * + * The macros take a subset of these arguments in the order listed here: + * + * CDATA: A pointer to the H5T_cdata_t structure that was passed to the + * conversion function. + * + * STYPE: The hid_t value for the source datatype. + * + * DTYPE: The hid_t value for the destination datatype. + * + * BUF: A pointer to the conversion buffer. + * + * NELMTS: The number of values to be converted. + * + * ST: The C name for source datatype (e.g., int) + * + * DT: The C name for the destination datatype (e.g., signed char) + * + * D_MIN: The minimum possible destination value. For unsigned + * destination types this should be zero. For signed destination + * types it's a negative value with a magnitude that is usually + * one greater than D_MAX. Source values which are smaller than + * D_MIN generate overflows. + * + * D_MAX: The maximum possible destination value. Source values which + * are larger than D_MAX generate overflows. + * + * The macros are implemented with a generic programming technique, similar + * to templates in C++. The macro which defines the "core" part of the + * conversion (which actually moves the data from the source to the destination) + * is invoked inside the H5T_CONV "template" macro by "gluing" it together, + * which allows the core conversion macro to be invoked as necessary. + * + * "Core" macros come in two flavors: one which calls the exception handling + * routine and one which doesn't (the "_NOEX" variant). The presence of the + * exception handling routine is detected before the loop over the values and + * the appropriate core routine loop is executed. + * + * The generic "core" macros are: (others are specific to particular conversion) + * + * Suffix Description + * ------ ----------- + * xX: Generic Conversion where the destination is at least as + * wide as the source. This case cannot generate overflows. + * + * Xx: Generic signed conversion where the source is at least as large + * as the destination. Overflows can occur when the destination is + * narrower than the source. + * + * Ux: Generic conversion for the `Us', `Uu' & `us' cases. + * Overflow occurs when the source magnitude is too large for the + * destination. + * + */ +#define H5T_CONV_xX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_xX_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + *(D) = (DT)(*(S)); \ + } + +/* Added a condition branch(else if (*(S) == (DT)(D_MAX))) which seems redundant. + * It handles a special situation when the source is "float" and assigned the value + * of "INT_MAX". A compiler may do roundup making this value "INT_MAX+1". However, + * when do comparison "if (*(S) > (DT)(D_MAX))", the compiler may consider them + * equal. In this case, do not return exception but make sure the maximum is assigned + * to the destination. SLU - 2005/06/29 + */ +#define H5T_CONV_Xx_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(D_MAX); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else if (*(S) < (ST)(D_MIN)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(D_MIN); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_Xx_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX)) { \ + *(D) = (DT)(D_MAX); \ + } \ + else if (*(S) < (ST)(D_MIN)) { \ + *(D) = (DT)(D_MIN); \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } + +#define H5T_CONV_Ux_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(D_MAX); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_Ux_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX)) { \ + *(D) = (DT)(D_MAX); \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } + +#define H5T_CONV_sS(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ + H5T_CONV(H5T_CONV_xX, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_sU_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) < 0) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = 0; \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_sU_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) < 0) \ + *(D) = 0; \ + else \ + *(D) = (DT)(*(S)); \ + } + +#define H5T_CONV_sU(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ + H5T_CONV(H5T_CONV_sU, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +/* Define to 1 if overflow is possible during conversion, 0 otherwise + * Because destination is at least as wide as the source, this should only + * occur between types of equal size */ +#define H5T_CONV_uS_UCHAR_SHORT 0 +#define H5T_CONV_uS_UCHAR_INT 0 +#define H5T_CONV_uS_UCHAR_LONG 0 +#define H5T_CONV_uS_UCHAR_LLONG 0 +#if H5_SIZEOF_SHORT == H5_SIZEOF_INT +#define H5T_CONV_uS_USHORT_INT 1 +#else +#define H5T_CONV_uS_USHORT_INT 0 +#endif +#define H5T_CONV_uS_USHORT_LONG 0 +#define H5T_CONV_uS_USHORT_LLONG 0 +#if H5_SIZEOF_INT == H5_SIZEOF_LONG +#define H5T_CONV_uS_UINT_LONG 1 +#else +#define H5T_CONV_uS_UINT_LONG 0 +#endif +#define H5T_CONV_uS_UINT_LLONG 0 +#if H5_SIZEOF_LONG == H5_SIZEOF_LONG_LONG +#define H5T_CONV_uS_ULONG_LLONG 1 +#else +#define H5T_CONV_uS_ULONG_LLONG 0 +#endif + +/* Note. If an argument is stringified or concatenated, the prescan does not + * occur. To expand the macro, then stringify or concatenate its expansion, + * one macro must call another macro that does the stringification or + * concatenation. */ +#define H5T_CONV_uS_EVAL_TYPES(STYPE, DTYPE) H5_GLUE4(H5T_CONV_uS_, STYPE, _, DTYPE) + +/* Called if overflow is possible */ +#define H5T_CONV_uS_CORE_1(S, D, ST, DT, D_MIN, D_MAX) \ + if (*(S) > (DT)(D_MAX)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler */ \ + *(D) = (DT)(D_MAX); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if (except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); + +/* Called if no overflow is possible */ +#define H5T_CONV_uS_CORE_0(S, D, ST, DT, D_MIN, D_MAX) *(D) = (DT)(*(S)); + +#define H5T_CONV_uS_CORE_I(over, S, D, ST, DT, D_MIN, D_MAX) \ + H5_GLUE(H5T_CONV_uS_CORE_, over)(S, D, ST, DT, D_MIN, D_MAX) + +#define H5T_CONV_uS_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + H5T_CONV_uS_CORE_I(H5T_CONV_uS_EVAL_TYPES(STYPE, DTYPE), S, D, ST, DT, D_MIN, D_MAX) \ + } + +/* Called if overflow is possible */ +#define H5T_CONV_uS_NOEX_CORE_1(S, D, ST, DT, D_MIN, D_MAX) \ + if (*(S) > (DT)(D_MAX)) \ + *(D) = (D_MAX); \ + else \ + *(D) = (DT)(*(S)); + +/* Called if no overflow is possible */ +#define H5T_CONV_uS_NOEX_CORE_0(S, D, ST, DT, D_MIN, D_MAX) *(D) = (DT)(*(S)); + +#define H5T_CONV_uS_NOEX_CORE_I(over, S, D, ST, DT, D_MIN, D_MAX) \ + H5_GLUE(H5T_CONV_uS_NOEX_CORE_, over)(S, D, ST, DT, D_MIN, D_MAX) + +#define H5T_CONV_uS_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + H5T_CONV_uS_NOEX_CORE_I(H5T_CONV_uS_EVAL_TYPES(STYPE, DTYPE), S, D, ST, DT, D_MIN, D_MAX) \ + } + +#define H5T_CONV_uS(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ + H5T_CONV(H5T_CONV_uS, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_uU(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ + H5T_CONV(H5T_CONV_xX, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_Ss(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ + H5T_CONV(H5T_CONV_Xx, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_Su_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) < 0) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = 0; \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else if (sizeof(ST) > sizeof(DT) && *(S) > (ST)(D_MAX)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(D_MAX); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_Su_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) < 0) \ + *(D) = 0; \ + else if (sizeof(ST) > sizeof(DT) && *(S) > (ST)(D_MAX)) \ + *(D) = (DT)(D_MAX); \ + else \ + *(D) = (DT)(*(S)); \ + } + +#define H5T_CONV_Su(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ + H5T_CONV(H5T_CONV_Su, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_Us(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ + H5T_CONV(H5T_CONV_Ux, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_Uu(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ + H5T_CONV(H5T_CONV_Ux, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_su_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + /* Assumes memory format of unsigned & signed integers is same */ \ + if (*(S) < 0) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = 0; \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_su_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + /* Assumes memory format of unsigned & signed integers is same */ \ + if (*(S) < 0) \ + *(D) = 0; \ + else \ + *(D) = (DT)(*(S)); \ + } + +#define H5T_CONV_su(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) == sizeof(DT)); \ + H5T_CONV(H5T_CONV_su, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_us_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + /* Assumes memory format of unsigned & signed integers is same */ \ + if (*(S) > (ST)(D_MAX)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(D_MAX); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_us_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + /* Assumes memory format of unsigned & signed integers is same */ \ + if (*(S) > (ST)(D_MAX)) \ + *(D) = (DT)(D_MAX); \ + else \ + *(D) = (DT)(*(S)); \ + } + +#define H5T_CONV_us(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) == sizeof(DT)); \ + H5T_CONV(H5T_CONV_us, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_fF(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ + H5T_CONV(H5T_CONV_xX, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +/* Same as H5T_CONV_Xx_CORE, except that instead of using D_MAX and D_MIN + * when an overflow occurs, use the 'float' infinity values. + */ +#define H5T_CONV_Ff_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else if (*(S) < (ST)(D_MIN)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_Ff_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX)) \ + *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \ + else if (*(S) < (ST)(D_MIN)) \ + *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \ + else \ + *(D) = (DT)(*(S)); \ + } + +#define H5T_CONV_Ff(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ + H5T_CONV(H5T_CONV_Ff, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_HI_LO_BIT_SET(TYP, V, LO, HI) \ + { \ + unsigned count; \ + unsigned char p; \ + unsigned u; \ + \ + count = 0; \ + for (u = 0; u < sizeof(TYP); u++) { \ + count = (((unsigned)sizeof(TYP) - 1) - u) * 8; \ + p = (unsigned char)((V) >> count); \ + if (p > 0) { \ + if (p & 0x80) \ + count += 7; \ + else if (p & 0x40) \ + count += 6; \ + else if (p & 0x20) \ + count += 5; \ + else if (p & 0x10) \ + count += 4; \ + else if (p & 0x08) \ + count += 3; \ + else if (p & 0x04) \ + count += 2; \ + else if (p & 0x02) \ + count += 1; \ + break; \ + } /* end if */ \ + } /* end for */ \ + \ + HI = count; \ + \ + count = 0; \ + for (u = 0; u < sizeof(TYP); u++) { \ + p = (unsigned char)((V) >> (u * 8)); \ + if (p > 0) { \ + count = u * 8; \ + \ + if (p & 0x01) \ + ; \ + else if (p & 0x02) \ + count += 1; \ + else if (p & 0x04) \ + count += 2; \ + else if (p & 0x08) \ + count += 3; \ + else if (p & 0x10) \ + count += 4; \ + else if (p & 0x20) \ + count += 5; \ + else if (p & 0x40) \ + count += 6; \ + else if (p & 0x80) \ + count += 7; \ + break; \ + } /* end if */ \ + } /* end for */ \ + \ + LO = count; \ + } + +#define H5T_CONV_xF_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (sprec > dprec) { \ + unsigned low_bit_pos, high_bit_pos; \ + \ + /* Detect high & low bits set in source */ \ + H5T_HI_LO_BIT_SET(ST, *(S), low_bit_pos, high_bit_pos) \ + \ + /* Check for more bits of precision in src than available in dst */ \ + if ((high_bit_pos - low_bit_pos) >= dprec) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_PRECISION, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, \ + S, D, conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(*(S)); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_xF_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + *(D) = (DT)(*(S)); \ + } + +#define H5T_CONV_xF(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + H5T_CONV(H5T_CONV_xF, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, Y) \ + } while (0) + +/* Quincey added the condition branch (else if (*(S) != (ST)((DT)(*(S))))). + * It handles a special situation when the source is "float" and assigned the value + * of "INT_MAX". Compilers do roundup making this value "INT_MAX+1". This branch + * is to check that situation and return exception for some compilers, mainly GCC. + * The branch if (*(S) > (DT)(D_MAX) || (sprec < dprec && *(S) == + * (ST)(D_MAX))) is for some compilers like Sun, HP, IBM, and SGI where under + * the same situation the "int" doesn't overflow. SLU - 2005/9/12 + */ +#define H5T_CONV_Fx_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX) || (sprec < dprec && *(S) == (ST)(D_MAX))) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(D_MAX); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else if (*(S) < (ST)(D_MIN)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(D_MIN); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else if (*(S) != (ST)((DT)(*(S)))) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_TRUNCATE, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(*(S)); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_Fx_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX)) \ + *(D) = (DT)(D_MAX); \ + else if (*(S) < (ST)(D_MIN)) \ + *(D) = (DT)(D_MIN); \ + else \ + *(D) = (DT)(*(S)); \ + } + +#define H5T_CONV_Fx(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + H5T_CONV(H5T_CONV_Fx, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, Y) \ + } while (0) + +#define H5T_CONV_fX(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) <= sizeof(DT)); \ + H5T_CONV(H5T_CONV_xX, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, N) \ + } while (0) + +#define H5T_CONV_Xf_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX) || (sprec < dprec && *(S) == (ST)(D_MAX))) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_HI, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else if (*(S) < (ST)(D_MIN)) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_RANGE_LOW, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, S, D, \ + conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else if (sprec > dprec) { \ + unsigned low_bit_pos, high_bit_pos; \ + \ + /* Detect high & low bits set in source */ \ + H5T_HI_LO_BIT_SET(ST, *(S), low_bit_pos, high_bit_pos) \ + \ + /* Check for more bits of precision in src than available in dst */ \ + if ((high_bit_pos - low_bit_pos) >= dprec) { \ + H5T_conv_ret_t except_ret = (conv_ctx->u.conv.cb_struct.func)( \ + H5T_CONV_EXCEPT_PRECISION, conv_ctx->u.conv.src_type_id, conv_ctx->u.conv.dst_type_id, \ + S, D, conv_ctx->u.conv.cb_struct.user_data); \ + if (except_ret == H5T_CONV_UNHANDLED) \ + /* Let compiler convert if case is ignored by user handler*/ \ + *(D) = (DT)(*(S)); \ + else if (except_ret == H5T_CONV_ABORT) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception"); \ + /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } \ + else \ + *(D) = (DT)(*(S)); \ + } +#define H5T_CONV_Xf_NOEX_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + if (*(S) > (ST)(D_MAX)) \ + *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _POS_INF_g); \ + else { \ + intmax_t s_cast = (intmax_t)(*(S)); \ + intmax_t d_cast = (intmax_t)(D_MAX); \ + \ + /* Check if source value would underflow destination. Do NOT do this \ + * by comparing against D_MIN casted to type ST here, as this will \ + * generally be undefined behavior (casting negative float value <= 1.0 \ + * to integer) for all floating point types and some compilers optimize \ + * this in a way that causes unexpected behavior. Instead, grab the \ + * absolute value of the source value first, then compare it to D_MAX. \ + */ \ + if (s_cast != INTMAX_MIN) \ + s_cast = imaxabs(s_cast); \ + else { \ + /* Handle two's complement integer representations where abs(INTMAX_MIN) \ + * can't be represented. Other representations will fall here as well, \ + * but this should be fine. \ + */ \ + s_cast = INTMAX_MAX; \ + d_cast -= 1; \ + } \ + \ + if (s_cast > d_cast) \ + *(D) = H5_GLUE3(H5T_NATIVE_, DTYPE, _NEG_INF_g); \ + else \ + *(D) = (DT)(*(S)); \ + } \ + } + +#define H5T_CONV_Xf(STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + do { \ + HDcompile_assert(sizeof(ST) >= sizeof(DT)); \ + H5T_CONV(H5T_CONV_Xf, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, Y) \ + } while (0) + +/* Since all "no exception" cores do the same thing (assign the value in the + * source location to the destination location, using casting), use one "core" + * to do them all. + */ +#ifndef H5_WANT_DCONV_EXCEPTION +#define H5T_CONV_NO_EXCEPT_CORE(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + { \ + *(D) = (DT)(*(S)); \ + } +#endif /* H5_WANT_DCONV_EXCEPTION */ + +/* Declare the source & destination precision variables */ +#define H5T_CONV_DECL_PREC(PREC) H5_GLUE(H5T_CONV_DECL_PREC_, PREC) + +#define H5T_CONV_DECL_PREC_Y \ + size_t sprec; /*source precision */ \ + size_t dprec; /*destination precision */ \ + H5T_class_t tclass; /*datatype's class */ + +#define H5T_CONV_DECL_PREC_N /*no precision variables */ + +/* Initialize the source & destination precision variables */ +#define H5T_CONV_SET_PREC(PREC) H5_GLUE(H5T_CONV_SET_PREC_, PREC) + +#define H5T_CONV_SET_PREC_Y \ + /* Get source & destination precisions into a variable */ \ + tclass = st->shared->type; \ + assert(tclass == H5T_INTEGER || tclass == H5T_FLOAT); \ + if (tclass == H5T_INTEGER) \ + sprec = st->shared->u.atomic.prec; \ + else \ + sprec = 1 + st->shared->u.atomic.u.f.msize; \ + tclass = dt->shared->type; \ + assert(tclass == H5T_INTEGER || tclass == H5T_FLOAT); \ + if (tclass == H5T_INTEGER) \ + dprec = dt->shared->u.atomic.prec; \ + else \ + dprec = 1 + dt->shared->u.atomic.u.f.msize; + +#define H5T_CONV_SET_PREC_N /*don't init precision variables */ + +/* Macro defining action on source data which needs to be aligned (before main action) */ +#define H5T_CONV_LOOP_PRE_SALIGN(ST) \ + { \ + /* The uint8_t * cast is required to avoid tripping over undefined behavior. \ + * \ + * The typed pointer arrives via a void pointer, which may have any alignment. \ + * We then cast it to a pointer to a type that is assumed to be aligned, which \ + * is undefined behavior (section 6.3.2.3 paragraph 7 of the C99 standard). \ + * In the past this hasn't caused many problems, but in some cases (e.g. \ + * converting long doubles on macOS), an optimizing compiler might do the \ + * wrong thing (in the macOS case, the conversion uses SSE, which has stricter \ + * requirements about alignment). \ + */ \ + H5MM_memcpy(&src_aligned, (const uint8_t *)src, sizeof(ST)); \ + } + +/* Macro defining action on source data which doesn't need to be aligned (before main action) */ +#define H5T_CONV_LOOP_PRE_SNOALIGN(ST) \ + { \ + } + +/* Macro defining action on destination data which needs to be aligned (before main action) */ +#define H5T_CONV_LOOP_PRE_DALIGN(DT) \ + { \ + d = &dst_aligned; \ + } + +/* Macro defining action on destination data which doesn't need to be aligned (before main action) */ +#define H5T_CONV_LOOP_PRE_DNOALIGN(DT) \ + { \ + } + +/* Macro defining action on source data which needs to be aligned (after main action) */ +#define H5T_CONV_LOOP_POST_SALIGN(ST) \ + { \ + } + +/* Macro defining action on source data which doesn't need to be aligned (after main action) */ +#define H5T_CONV_LOOP_POST_SNOALIGN(ST) \ + { \ + } + +/* Macro defining action on destination data which needs to be aligned (after main action) */ +#define H5T_CONV_LOOP_POST_DALIGN(DT) \ + { \ + /* The uint8_t * cast is required to avoid tripping over undefined behavior. \ + * \ + * The typed pointer arrives via a void pointer, which may have any alignment. \ + * We then cast it to a pointer to a type that is assumed to be aligned, which \ + * is undefined behavior (section 6.3.2.3 paragraph 7 of the C99 standard). \ + * In the past this hasn't caused many problems, but in some cases (e.g. \ + * converting long doubles on macOS), an optimizing compiler might do the \ + * wrong thing (in the macOS case, the conversion uses SSE, which has stricter \ + * requirements about alignment). \ + */ \ + H5MM_memcpy((uint8_t *)dst, &dst_aligned, sizeof(DT)); \ + } + +/* Macro defining action on destination data which doesn't need to be aligned (after main action) */ +#define H5T_CONV_LOOP_POST_DNOALIGN(DT) \ + { \ + } + +/* The outer wrapper for the type conversion loop, to check for an exception handling routine */ +#define H5T_CONV_LOOP_OUTER(PRE_SALIGN_GUTS, PRE_DALIGN_GUTS, POST_SALIGN_GUTS, POST_DALIGN_GUTS, GUTS, \ + STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + if (conv_ctx->u.conv.cb_struct.func) { \ + H5T_CONV_LOOP(PRE_SALIGN_GUTS, PRE_DALIGN_GUTS, POST_SALIGN_GUTS, POST_DALIGN_GUTS, GUTS, STYPE, \ + DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + } \ + else { \ + H5T_CONV_LOOP(PRE_SALIGN_GUTS, PRE_DALIGN_GUTS, POST_SALIGN_GUTS, POST_DALIGN_GUTS, \ + H5_GLUE(GUTS, _NOEX), STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + } + +/* Macro to call the actual "guts" of the type conversion, or call the "no exception" guts */ +#ifdef H5_WANT_DCONV_EXCEPTION +#define H5T_CONV_LOOP_GUTS(GUTS, STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + /* ... user-defined stuff here -- the conversion ... */ \ + H5_GLUE(GUTS, _CORE)(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) +#else /* H5_WANT_DCONV_EXCEPTION */ +#define H5T_CONV_LOOP_GUTS(GUTS, STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + H5_GLUE(H5T_CONV_NO_EXCEPT, _CORE)(STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) +#endif /* H5_WANT_DCONV_EXCEPTION */ + +/* The inner loop of the type conversion macro, actually converting the elements */ +#define H5T_CONV_LOOP(PRE_SALIGN_GUTS, PRE_DALIGN_GUTS, POST_SALIGN_GUTS, POST_DALIGN_GUTS, GUTS, STYPE, \ + DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + for (elmtno = 0; elmtno < safe; elmtno++) { \ + /* Handle source pre-alignment */ \ + H5_GLUE(H5T_CONV_LOOP_, PRE_SALIGN_GUTS) \ + (ST) \ + \ + /* Handle destination pre-alignment */ \ + H5_GLUE(H5T_CONV_LOOP_, PRE_DALIGN_GUTS)(DT) \ + \ + /* ... user-defined stuff here -- the conversion ... */ \ + H5T_CONV_LOOP_GUTS(GUTS, STYPE, DTYPE, S, D, ST, DT, D_MIN, D_MAX) \ + \ + /* Handle source post-alignment */ \ + H5_GLUE(H5T_CONV_LOOP_, POST_SALIGN_GUTS)(ST) \ + \ + /* Handle destination post-alignment */ \ + H5_GLUE(H5T_CONV_LOOP_, POST_DALIGN_GUTS)(DT) \ + \ + /* Advance pointers */ \ + src_buf = (void *)((uint8_t *)src_buf + s_stride); \ + src = (ST *)src_buf; \ + dst_buf = (void *)((uint8_t *)dst_buf + d_stride); \ + dst = (DT *)dst_buf; \ + } + +/* The main part of every integer hardware conversion macro */ +#define H5T_CONV(GUTS, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, PREC) \ + { \ + herr_t ret_value = SUCCEED; /* Return value */ \ + \ + FUNC_ENTER_PACKAGE \ + \ + { \ + size_t elmtno; /*element number */ \ + H5T_CONV_DECL_PREC(PREC) /*declare precision variables, or not */ \ + void *src_buf; /*'raw' source buffer */ \ + void *dst_buf; /*'raw' destination buffer */ \ + ST *src, *s; /*source buffer */ \ + DT *dst, *d; /*destination buffer */ \ + ST src_aligned; /*source aligned type */ \ + DT dst_aligned; /*destination aligned type */ \ + bool s_mv, d_mv; /*move data to align it? */ \ + ssize_t s_stride, d_stride; /*src and dst strides */ \ + size_t safe; /*how many elements are safe to process in each pass */ \ + \ + switch (cdata->command) { \ + case H5T_CONV_INIT: \ + /* Sanity check and initialize statistics */ \ + cdata->need_bkg = H5T_BKG_NO; \ + if (NULL == st || NULL == dt) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype"); \ + if (st->shared->size != sizeof(ST) || dt->shared->size != sizeof(DT)) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "disagreement about datatype size"); \ + CI_ALLOC_PRIV \ + break; \ + \ + case H5T_CONV_FREE: \ + /* Print and free statistics */ \ + CI_PRINT_STATS(STYPE, DTYPE); \ + CI_FREE_PRIV \ + break; \ + \ + case H5T_CONV_CONV: \ + if (NULL == st || NULL == dt) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype"); \ + if (NULL == conv_ctx) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \ + "invalid datatype conversion context pointer"); \ + \ + /* Initialize source & destination strides */ \ + if (buf_stride) { \ + assert(buf_stride >= sizeof(ST)); \ + assert(buf_stride >= sizeof(DT)); \ + s_stride = d_stride = (ssize_t)buf_stride; \ + } \ + else { \ + s_stride = sizeof(ST); \ + d_stride = sizeof(DT); \ + } \ + \ + /* Is alignment required for source or dest? */ \ + s_mv = H5T_NATIVE_##STYPE##_ALIGN_g > 1 && \ + ((size_t)buf % H5T_NATIVE_##STYPE##_ALIGN_g || \ + /* Cray */ ((size_t)((ST *)buf) != (size_t)buf) || \ + (size_t)s_stride % H5T_NATIVE_##STYPE##_ALIGN_g); \ + d_mv = H5T_NATIVE_##DTYPE##_ALIGN_g > 1 && \ + ((size_t)buf % H5T_NATIVE_##DTYPE##_ALIGN_g || \ + /* Cray */ ((size_t)((DT *)buf) != (size_t)buf) || \ + (size_t)d_stride % H5T_NATIVE_##DTYPE##_ALIGN_g); \ + CI_INC_SRC(s_mv) \ + CI_INC_DST(d_mv) \ + \ + H5T_CONV_SET_PREC(PREC) /*init precision variables, or not */ \ + \ + /* The outer loop of the type conversion macro, controlling which */ \ + /* direction the buffer is walked */ \ + while (nelmts > 0) { \ + /* Check if we need to go backwards through the buffer */ \ + if (d_stride > s_stride) { \ + /* Compute the number of "safe" destination elements at */ \ + /* the end of the buffer (Those which don't overlap with */ \ + /* any source elements at the beginning of the buffer) */ \ + safe = nelmts - (((nelmts * (size_t)s_stride) + (size_t)(d_stride - 1)) / \ + (size_t)d_stride); \ + \ + /* If we're down to the last few elements, just wrap up */ \ + /* with a "real" reverse copy */ \ + if (safe < 2) { \ + src = (ST *)(src_buf = (void *)((uint8_t *)buf + \ + (nelmts - 1) * (size_t)s_stride)); \ + dst = (DT *)(dst_buf = (void *)((uint8_t *)buf + \ + (nelmts - 1) * (size_t)d_stride)); \ + s_stride = -s_stride; \ + d_stride = -d_stride; \ + \ + safe = nelmts; \ + } /* end if */ \ + else { \ + src = (ST *)(src_buf = (void *)((uint8_t *)buf + \ + (nelmts - safe) * (size_t)s_stride)); \ + dst = (DT *)(dst_buf = (void *)((uint8_t *)buf + \ + (nelmts - safe) * (size_t)d_stride)); \ + } /* end else */ \ + } /* end if */ \ + else { \ + /* Single forward pass over all data */ \ + src = (ST *)(src_buf = buf); \ + dst = (DT *)(dst_buf = buf); \ + safe = nelmts; \ + } /* end else */ \ + \ + /* Perform loop over elements to convert */ \ + if (s_mv && d_mv) { \ + /* Alignment is required for both source and dest */ \ + s = &src_aligned; \ + H5T_CONV_LOOP_OUTER(PRE_SALIGN, PRE_DALIGN, POST_SALIGN, POST_DALIGN, GUTS, \ + STYPE, DTYPE, s, d, ST, DT, D_MIN, D_MAX) \ + } \ + else if (s_mv) { \ + /* Alignment is required only for source */ \ + s = &src_aligned; \ + H5T_CONV_LOOP_OUTER(PRE_SALIGN, PRE_DNOALIGN, POST_SALIGN, POST_DNOALIGN, GUTS, \ + STYPE, DTYPE, s, dst, ST, DT, D_MIN, D_MAX) \ + } \ + else if (d_mv) { \ + /* Alignment is required only for destination */ \ + H5T_CONV_LOOP_OUTER(PRE_SNOALIGN, PRE_DALIGN, POST_SNOALIGN, POST_DALIGN, GUTS, \ + STYPE, DTYPE, src, d, ST, DT, D_MIN, D_MAX) \ + } \ + else { \ + /* Alignment is not required for both source and destination */ \ + H5T_CONV_LOOP_OUTER(PRE_SNOALIGN, PRE_DNOALIGN, POST_SNOALIGN, POST_DNOALIGN, \ + GUTS, STYPE, DTYPE, src, dst, ST, DT, D_MIN, D_MAX) \ + } \ + \ + /* Decrement number of elements left to convert */ \ + nelmts -= safe; \ + } /* end while */ \ + break; \ + \ + default: \ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); \ + } \ + } \ + \ +done: \ + FUNC_LEAVE_NOAPI(ret_value) \ + } + +#ifdef H5T_DEBUG + +/* Print alignment statistics */ +#define CI_PRINT_STATS(STYPE, DTYPE) \ + do { \ + if (H5DEBUG(T) && ((H5T_conv_hw_t *)cdata->priv)->s_aligned) { \ + fprintf(H5DEBUG(T), " %zu src elements aligned on %zu-byte boundaries\n", \ + ((H5T_conv_hw_t *)cdata->priv)->s_aligned, H5T_NATIVE_##STYPE##_ALIGN_g); \ + } \ + if (H5DEBUG(T) && ((H5T_conv_hw_t *)cdata->priv)->d_aligned) { \ + fprintf(H5DEBUG(T), " %zu dst elements aligned on %zu-byte boundaries\n", \ + ((H5T_conv_hw_t *)cdata->priv)->d_aligned, H5T_NATIVE_##DTYPE##_ALIGN_g); \ + } \ + } while (0) + +/* Allocate private alignment structure for atomic types */ +#define CI_ALLOC_PRIV \ + if (NULL == (cdata->priv = H5MM_calloc(sizeof(H5T_conv_hw_t)))) { \ + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); \ + } + +/* Free private alignment structure for atomic types */ +#define CI_FREE_PRIV \ + if (cdata->priv != NULL) \ + cdata->priv = H5MM_xfree(cdata->priv); + +/* Increment source alignment counter */ +#define CI_INC_SRC(s) \ + if (s) \ + ((H5T_conv_hw_t *)cdata->priv)->s_aligned += nelmts; + +/* Increment destination alignment counter */ +#define CI_INC_DST(d) \ + if (d) \ + ((H5T_conv_hw_t *)cdata->priv)->d_aligned += nelmts; +#else /* H5T_DEBUG */ +#define CI_PRINT_STATS(STYPE, DTYPE) /*void*/ +#define CI_ALLOC_PRIV cdata->priv = NULL; +#define CI_FREE_PRIV /* void */ +#define CI_INC_SRC(s) /* void */ +#define CI_INC_DST(d) /* void */ +#endif /* H5T_DEBUG */ + +#endif /* H5Tconv_macros_H */ diff --git a/src/H5Tconv_reference.c b/src/H5Tconv_reference.c new file mode 100644 index 00000000000..62ad0b574c0 --- /dev/null +++ b/src/H5Tconv_reference.c @@ -0,0 +1,307 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Datatype conversion functions for reference datatypes + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ +#define H5R_FRIEND /* Suppress error about including H5Rpkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5Eprivate.h" +#include "H5FLprivate.h" +#include "H5Rpkg.h" +#include "H5Tconv.h" +#include "H5Tconv_reference.h" + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage pieces of reference data */ +H5FL_BLK_DEFINE_STATIC(ref_seq); + +/*------------------------------------------------------------------------- + * Function: H5T__conv_ref + * + * Purpose: Converts between reference datatypes in memory and on disk. + * This is a soft conversion function. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ref(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg) +{ + uint8_t *s = NULL; /* source buffer */ + uint8_t *d = NULL; /* destination buffer */ + uint8_t *b = NULL; /* background buffer */ + ssize_t s_stride = 0; /* src stride */ + ssize_t d_stride = 0; /* dst stride */ + ssize_t b_stride; /* bkg stride */ + size_t safe = 0; /* how many elements are safe to process in each pass */ + void *conv_buf = NULL; /* temporary conversion buffer */ + size_t conv_buf_size = 0; /* size of conversion buffer in bytes */ + size_t elmtno = 0; /* element number counter */ + size_t orig_d_stride = 0; /* Original destination stride (used for error handling) */ + size_t orig_nelmts = nelmts; /* Original # of elements to convert (used for error handling) */ + bool convert_forward = + true; /* Current direction of conversion (forward or backward, used for error handling) */ + bool conversions_made = + false; /* Flag to indicate conversions have been performed, used for error handling */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* + * First, determine if this conversion function applies to the + * conversion path SRC-->DST. If not, return failure; + * otherwise initialize the `priv' field of `cdata' with + * information that remains (almost) constant for this + * conversion path. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); + if (H5T_REFERENCE != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype"); + if (H5T_REFERENCE != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype"); + /* Only allow for source reference that is not an opaque type, destination must be opaque */ + if (!dst->shared->u.atomic.u.r.opaque) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not an H5T_STD_REF datatype"); + + /* Reference types don't need a background buffer */ + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: { + /* + * Conversion. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + + assert(src->shared->u.atomic.u.r.cls); + + /* Initialize source & destination strides */ + if (buf_stride) { + assert(buf_stride >= src->shared->size); + assert(buf_stride >= dst->shared->size); + H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); + s_stride = d_stride = (ssize_t)buf_stride; + } /* end if */ + else { + H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); + H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); + s_stride = (ssize_t)src->shared->size; + d_stride = (ssize_t)dst->shared->size; + } /* end else */ + if (bkg) { + if (bkg_stride) + b_stride = (ssize_t)bkg_stride; + else + b_stride = d_stride; + } /* end if */ + else + b_stride = 0; + + /* Save info for unraveling on errors */ + orig_d_stride = (size_t)d_stride; + convert_forward = !(d_stride > s_stride); + + /* The outer loop of the type conversion macro, controlling which */ + /* direction the buffer is walked */ + while (nelmts > 0) { + /* Check if we need to go backwards through the buffer */ + if (d_stride > s_stride) { + /* Sanity check */ + assert(s_stride > 0); + assert(d_stride > 0); + assert(b_stride >= 0); + + /* Compute the number of "safe" destination elements at */ + /* the end of the buffer (Those which don't overlap with */ + /* any source elements at the beginning of the buffer) */ + safe = + nelmts - (((nelmts * (size_t)s_stride) + ((size_t)d_stride - 1)) / (size_t)d_stride); + + /* If we're down to the last few elements, just wrap up */ + /* with a "real" reverse copy */ + if (safe < 2) { + s = (uint8_t *)buf + (nelmts - 1) * (size_t)s_stride; + d = (uint8_t *)buf + (nelmts - 1) * (size_t)d_stride; + if (bkg) + b = (uint8_t *)bkg + (nelmts - 1) * (size_t)b_stride; + s_stride = -s_stride; + d_stride = -d_stride; + b_stride = -b_stride; + + safe = nelmts; + } /* end if */ + else { + s = (uint8_t *)buf + (nelmts - safe) * (size_t)s_stride; + d = (uint8_t *)buf + (nelmts - safe) * (size_t)d_stride; + if (bkg) + b = (uint8_t *)bkg + (nelmts - safe) * (size_t)b_stride; + } /* end else */ + } /* end if */ + else { + /* Single forward pass over all data */ + s = d = (uint8_t *)buf; + b = (uint8_t *)bkg; + safe = nelmts; + } /* end else */ + + for (elmtno = 0; elmtno < safe; elmtno++) { + size_t buf_size; + bool dst_copy = false; + bool is_nil; /* Whether reference is "nil" */ + + /* Check for "nil" source reference */ + if ((*(src->shared->u.atomic.u.r.cls->isnull))(src->shared->u.atomic.u.r.file, s, + &is_nil) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, + "can't check if reference data is 'nil'"); + + if (is_nil) { + /* Write "nil" reference to destination location */ + if ((*(dst->shared->u.atomic.u.r.cls->setnull))(dst->shared->u.atomic.u.r.file, d, + b) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, + "can't set reference data to 'nil'"); + } /* end else-if */ + else { + /* Get size of references */ + if (0 == (buf_size = src->shared->u.atomic.u.r.cls->getsize( + src->shared->u.atomic.u.r.file, s, src->shared->size, + dst->shared->u.atomic.u.r.file, &dst_copy))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to obtain size of reference"); + + /* Check if conversion buffer is large enough, resize if necessary. */ + if (conv_buf_size < buf_size) { + conv_buf_size = buf_size; + if (NULL == (conv_buf = H5FL_BLK_REALLOC(ref_seq, conv_buf, conv_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + memset(conv_buf, 0, conv_buf_size); + } /* end if */ + + if (dst_copy && (src->shared->u.atomic.u.r.loc == H5T_LOC_DISK)) + H5MM_memcpy(conv_buf, s, buf_size); + else { + /* Read reference */ + if (src->shared->u.atomic.u.r.cls->read( + src->shared->u.atomic.u.r.file, s, src->shared->size, + dst->shared->u.atomic.u.r.file, conv_buf, buf_size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read reference data"); + } /* end else */ + + if (dst_copy && (dst->shared->u.atomic.u.r.loc == H5T_LOC_DISK)) + H5MM_memcpy(d, conv_buf, buf_size); + else { + /* Write reference to destination location */ + if (dst->shared->u.atomic.u.r.cls->write( + src->shared->u.atomic.u.r.file, conv_buf, buf_size, + src->shared->u.atomic.u.r.rtype, dst->shared->u.atomic.u.r.file, d, + dst->shared->size, b) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write reference data"); + } /* end else */ + } /* end else */ + + /* Indicate that elements have been converted, in case of error */ + conversions_made = true; + + /* Advance pointers */ + s += s_stride; + d += d_stride; + + if (b) + b += b_stride; + } /* end for */ + + /* Decrement number of elements left to convert */ + nelmts -= safe; + } /* end while */ + } /* end case */ + break; + + default: /* Some other command we don't know about yet.*/ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + /* Release converted elements on error */ + if (ret_value < 0 && conversions_made) { + H5R_ref_priv_t ref_priv; + size_t dest_count; + + /* Set up for first pass to destroy references */ + if (nelmts < orig_nelmts || (convert_forward && elmtno < safe)) { + dest_count = orig_nelmts - nelmts; + + /* Set pointer to correct location, based on direction chosen */ + if (convert_forward) { + d = (uint8_t *)buf; + dest_count += elmtno; /* Include partial iteration in first pass, for forward conversions */ + } + else + d = (uint8_t *)buf + (nelmts * orig_d_stride); + + /* Destroy references that have already been converted */ + while (dest_count > 0) { + memcpy(&ref_priv, d, sizeof(H5R_ref_priv_t)); + H5R__destroy(&ref_priv); /* Ignore errors at this point */ + d += orig_d_stride; + dest_count--; + } + } + + /* Do any remaining partial iteration, if converting backwards */ + if (!convert_forward && elmtno < safe) { + dest_count = elmtno; + + /* Set pointer to correct location */ + if (d_stride > 0) + d = (uint8_t *)buf + ((nelmts - safe) * orig_d_stride); + else + d = (uint8_t *)buf + ((nelmts - elmtno) * orig_d_stride); + + /* Destroy references that have already been converted */ + while (dest_count > 0) { + memcpy(&ref_priv, d, sizeof(H5R_ref_priv_t)); + H5R__destroy(&ref_priv); /* Ignore errors at this point */ + d += orig_d_stride; + dest_count--; + } + } + } + + /* Release the conversion buffer (always allocated, except on errors) */ + if (conv_buf) + conv_buf = H5FL_BLK_FREE(ref_seq, conv_buf); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_ref() */ diff --git a/src/H5Tconv_reference.h b/src/H5Tconv_reference.h new file mode 100644 index 00000000000..346dc947e94 --- /dev/null +++ b/src/H5Tconv_reference.h @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_reference_H +#define H5Tconv_reference_H + +/* Private headers needed by this file */ +#include "H5Tpkg.h" + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/****************************************/ +/* Soft (emulated) conversion functions */ +/****************************************/ + +/* Conversion functions between reference datatypes */ +H5_DLL herr_t H5T__conv_ref(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/*********************************************/ +/* Hard (compiler cast) conversion functions */ +/*********************************************/ + +#endif /* H5Tconv_reference_H */ diff --git a/src/H5Tconv_string.c b/src/H5Tconv_string.c new file mode 100644 index 00000000000..520d43e24c7 --- /dev/null +++ b/src/H5Tconv_string.c @@ -0,0 +1,267 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Datatype conversion functions for string datatypes + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5Eprivate.h" +#include "H5Tconv.h" +#include "H5Tconv_string.h" + +/*------------------------------------------------------------------------- + * Function: H5T__conv_s_s + * + * Purpose: Convert one fixed-length string type to another. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_s_s(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, + size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) +{ + ssize_t src_delta, dst_delta; /*source & destination stride */ + int direction; /*direction of traversal */ + size_t elmtno; /*element number */ + size_t olap; /*num overlapping elements */ + size_t nchars = 0; /*number of characters copied */ + uint8_t *s, *sp, *d, *dp; /*src and dst traversal pointers*/ + uint8_t *dbuf = NULL; /*temp buf for overlap converts. */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (8 * src->shared->size != src->shared->u.atomic.prec || + 8 * dst->shared->size != dst->shared->u.atomic.prec) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision"); + if (0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad offset"); + if (H5T_CSET_ASCII != src->shared->u.atomic.u.s.cset && + H5T_CSET_UTF8 != src->shared->u.atomic.u.s.cset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad source character set"); + if (H5T_CSET_ASCII != dst->shared->u.atomic.u.s.cset && + H5T_CSET_UTF8 != dst->shared->u.atomic.u.s.cset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad destination character set"); + if ((H5T_CSET_ASCII == src->shared->u.atomic.u.s.cset && + H5T_CSET_UTF8 == dst->shared->u.atomic.u.s.cset) || + (H5T_CSET_ASCII == dst->shared->u.atomic.u.s.cset && + H5T_CSET_UTF8 == src->shared->u.atomic.u.s.cset)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "The library doesn't convert between strings of ASCII and UTF"); + if (src->shared->u.atomic.u.s.pad < 0 || src->shared->u.atomic.u.s.pad >= H5T_NSTR || + dst->shared->u.atomic.u.s.pad < 0 || dst->shared->u.atomic.u.s.pad >= H5T_NSTR) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character padding"); + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + /* Get the datatypes */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + + /* + * Do we process the values from beginning to end or vice versa? Also, + * how many of the elements have the source and destination areas + * overlapping? + */ + if (src->shared->size == dst->shared->size || buf_stride) { + /* + * When the source and destination are the same size we can do + * all the conversions in place. + */ + sp = dp = (uint8_t *)buf; + direction = 1; + olap = 0; + } + else if (src->shared->size >= dst->shared->size) { + double olapd = + ceil((double)(dst->shared->size) / (double)(src->shared->size - dst->shared->size)); + olap = (size_t)olapd; + sp = dp = (uint8_t *)buf; + direction = 1; + } + else { + double olapd = + ceil((double)(src->shared->size) / (double)(dst->shared->size - src->shared->size)); + olap = (size_t)olapd; + sp = (uint8_t *)buf + (nelmts - 1) * src->shared->size; + dp = (uint8_t *)buf + (nelmts - 1) * dst->shared->size; + direction = -1; + } + + /* + * Direction & size of buffer traversal. + */ + H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); + H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); + H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); + src_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : src->shared->size); + dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst->shared->size); + + /* Allocate the overlap buffer */ + if (NULL == (dbuf = (uint8_t *)H5MM_calloc(dst->shared->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for string conversion"); + + /* The conversion loop. */ + for (elmtno = 0; elmtno < nelmts; elmtno++) { + + /* + * If the source and destination buffers overlap then use a + * temporary buffer for the destination. + */ + if (direction > 0) { + s = sp; + d = elmtno < olap ? dbuf : dp; + } + else { + s = sp; + d = elmtno + olap >= nelmts ? dbuf : dp; + } +#ifndef NDEBUG + /* I don't quite trust the overlap calculations yet */ + if (src->shared->size == dst->shared->size || buf_stride) { + assert(s == d); + } + else if (d == dbuf) { + assert((dp >= sp && dp < sp + src->shared->size) || + (sp >= dp && sp < dp + dst->shared->size)); + } + else { + assert((dp < sp && dp + dst->shared->size <= sp) || + (sp < dp && sp + src->shared->size <= dp)); + } +#endif + + /* Copy characters from source to destination */ + switch (src->shared->u.atomic.u.s.pad) { + case H5T_STR_NULLTERM: + for (nchars = 0; + nchars < dst->shared->size && nchars < src->shared->size && s[nchars]; + nchars++) { + d[nchars] = s[nchars]; + } + break; + + case H5T_STR_NULLPAD: + for (nchars = 0; + nchars < dst->shared->size && nchars < src->shared->size && s[nchars]; + nchars++) { + d[nchars] = s[nchars]; + } + break; + + case H5T_STR_SPACEPAD: + nchars = src->shared->size; + while (nchars > 0 && ' ' == s[nchars - 1]) + --nchars; + nchars = MIN(dst->shared->size, nchars); + if (d != s) + H5MM_memcpy(d, s, nchars); + break; + + case H5T_STR_RESERVED_3: + case H5T_STR_RESERVED_4: + case H5T_STR_RESERVED_5: + case H5T_STR_RESERVED_6: + case H5T_STR_RESERVED_7: + case H5T_STR_RESERVED_8: + case H5T_STR_RESERVED_9: + case H5T_STR_RESERVED_10: + case H5T_STR_RESERVED_11: + case H5T_STR_RESERVED_12: + case H5T_STR_RESERVED_13: + case H5T_STR_RESERVED_14: + case H5T_STR_RESERVED_15: + case H5T_STR_ERROR: + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "source string padding method not supported"); + } /* end switch */ + + /* Terminate or pad the destination */ + switch (dst->shared->u.atomic.u.s.pad) { + case H5T_STR_NULLTERM: + while (nchars < dst->shared->size) + d[nchars++] = '\0'; + d[dst->shared->size - 1] = '\0'; + break; + + case H5T_STR_NULLPAD: + while (nchars < dst->shared->size) + d[nchars++] = '\0'; + break; + + case H5T_STR_SPACEPAD: + while (nchars < dst->shared->size) + d[nchars++] = ' '; + break; + + case H5T_STR_RESERVED_3: + case H5T_STR_RESERVED_4: + case H5T_STR_RESERVED_5: + case H5T_STR_RESERVED_6: + case H5T_STR_RESERVED_7: + case H5T_STR_RESERVED_8: + case H5T_STR_RESERVED_9: + case H5T_STR_RESERVED_10: + case H5T_STR_RESERVED_11: + case H5T_STR_RESERVED_12: + case H5T_STR_RESERVED_13: + case H5T_STR_RESERVED_14: + case H5T_STR_RESERVED_15: + case H5T_STR_ERROR: + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "destination string padding method not supported"); + } /* end switch */ + + /* + * If we used a temporary buffer for the destination then we + * should copy the value to the true destination buffer. + */ + if (d == dbuf) + H5MM_memcpy(dp, d, dst->shared->size); + + /* Advance source & destination pointers by delta amounts */ + sp += src_delta; + dp += dst_delta; + } /* end for */ + break; + + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + H5MM_xfree(dbuf); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_s_s() */ diff --git a/src/H5CSprivate.h b/src/H5Tconv_string.h similarity index 54% rename from src/H5CSprivate.h rename to src/H5Tconv_string.h index 5cdf2d5fdd3..5a8a6354539 100644 --- a/src/H5CSprivate.h +++ b/src/H5Tconv_string.h @@ -10,21 +10,27 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* - * Header file for function stacks, etc. - */ -#ifndef H5CSprivate_H -#define H5CSprivate_H +#ifndef H5Tconv_string_H +#define H5Tconv_string_H /* Private headers needed by this file */ -#include "H5private.h" +#include "H5Tpkg.h" -/* Forward declarations for structure fields */ -struct H5CS_t; -H5_DLL herr_t H5CS_push(const char *func_name); -H5_DLL herr_t H5CS_pop(void); -H5_DLL herr_t H5CS_print_stack(const struct H5CS_t *stack, FILE *stream); -H5_DLL struct H5CS_t *H5CS_copy_stack(void); -H5_DLL herr_t H5CS_close_stack(struct H5CS_t *stack); +/***********************/ +/* Function Prototypes */ +/***********************/ -#endif /* H5CSprivate_H */ +/****************************************/ +/* Soft (emulated) conversion functions */ +/****************************************/ + +/* Conversion functions between string datatypes */ +H5_DLL herr_t H5T__conv_s_s(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *_buf, void *bkg); + +/*********************************************/ +/* Hard (compiler cast) conversion functions */ +/*********************************************/ + +#endif /* H5Tconv_string_H */ diff --git a/src/H5Tconv_vlen.c b/src/H5Tconv_vlen.c new file mode 100644 index 00000000000..ab6f5fc2d59 --- /dev/null +++ b/src/H5Tconv_vlen.c @@ -0,0 +1,590 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Datatype conversion functions for variable-length datatypes + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5CXprivate.h" +#include "H5Eprivate.h" +#include "H5Iprivate.h" +#include "H5Tconv.h" +#include "H5Tconv_vlen.h" + +/****************/ +/* Local Macros */ +/****************/ + +/* Minimum size of variable-length conversion buffer */ +#define H5T_VLEN_MIN_CONF_BUF_SIZE 4096 + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Local Prototypes */ +/********************/ + +static herr_t H5T__conv_vlen_nested_free(uint8_t *buf, H5T_t *dt); + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage pieces of vlen data */ +H5FL_BLK_DEFINE_STATIC(vlen_seq); + +/*------------------------------------------------------------------------- + * Function: H5T__conv_vlen_nested_free + * + * Purpose: Recursively locates and frees any nested VLEN components of + * complex data types (including COMPOUND). + * + * Return: Non-negative on success/Negative on failure. + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__conv_vlen_nested_free(uint8_t *buf, H5T_t *dt) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (dt->shared->type) { + case H5T_VLEN: + /* Pointer buf refers to VLEN data; free it (always reset tmp) */ + if ((*(dt->shared->u.vlen.cls->del))(dt->shared->u.vlen.file, buf) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free nested vlen"); + break; + + case H5T_COMPOUND: + /* Pointer buf refers to COMPOUND data; recurse for each member. */ + for (unsigned i = 0; i < dt->shared->u.compnd.nmembs; ++i) + if (H5T__conv_vlen_nested_free(buf + dt->shared->u.compnd.memb[i].offset, + dt->shared->u.compnd.memb[i].type) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free compound member"); + break; + + case H5T_ARRAY: + /* Pointer buf refers to ARRAY data; recurse for each element. */ + for (unsigned i = 0; i < dt->shared->u.array.nelem; ++i) + if (H5T__conv_vlen_nested_free(buf + i * dt->shared->parent->shared->size, + dt->shared->parent) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't free array data"); + break; + + case H5T_INTEGER: + case H5T_FLOAT: + case H5T_TIME: + case H5T_STRING: + case H5T_BITFIELD: + case H5T_OPAQUE: + case H5T_REFERENCE: + case H5T_ENUM: + /* These types cannot contain vl data */ + break; + + case H5T_NO_CLASS: + case H5T_NCLASSES: + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid datatype class"); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5T__conv_vlen_nested_free() */ + +/*------------------------------------------------------------------------- + * Function: H5T__conv_vlen + * + * Purpose: Converts between VL datatypes in memory and on disk. + * This is a soft conversion function. The algorithm is + * basically: + * + * For every VL struct in the main buffer: + * 1. Allocate space for temporary dst VL data (reuse buffer + * if possible) + * 2. Copy VL data from src buffer into dst buffer + * 3. Convert VL data into dst representation + * 4. Allocate buffer in dst heap + * 5. Free heap objects storing old data + * 6. Write dst VL data into dst heap + * 7. Store (heap ID or pointer) and length in main dst buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_vlen(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t *conv_ctx, + size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg) +{ + H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ + H5T_conv_ctx_t tmp_conv_ctx = {0}; /* Temporary conversion context */ + H5T_path_t *tpath = NULL; /* Type conversion path */ + bool noop_conv = false; /* Flag to indicate a noop conversion */ + bool write_to_file = false; /* Flag to indicate writing to file */ + htri_t parent_is_vlen; /* Flag to indicate parent is vlen datatype */ + size_t bg_seq_len = 0; /* The number of elements in the background sequence */ + H5T_t *tsrc_cpy = NULL; /* Temporary copy of source base datatype */ + H5T_t *tdst_cpy = NULL; /* Temporary copy of destination base datatype */ + hid_t tsrc_id = H5I_INVALID_HID; /* Temporary type atom */ + hid_t tdst_id = H5I_INVALID_HID; /* Temporary type atom */ + uint8_t *s = NULL; /* Source buffer */ + uint8_t *d = NULL; /* Destination buffer */ + uint8_t *b = NULL; /* Background buffer */ + ssize_t s_stride = 0; /* Src stride */ + ssize_t d_stride = 0; /* Dst stride */ + ssize_t b_stride; /* Bkg stride */ + size_t safe = 0; /* How many elements are safe to process in each pass */ + size_t src_base_size; /* Source base size*/ + size_t dst_base_size; /* Destination base size*/ + void *conv_buf = NULL; /* Temporary conversion buffer */ + size_t conv_buf_size = 0; /* Size of conversion buffer in bytes */ + void *tmp_buf = NULL; /* Temporary background buffer */ + size_t tmp_buf_size = 0; /* Size of temporary bkg buffer */ + bool nested = false; /* Flag of nested VL case */ + size_t elmtno = 0; /* Element number counter */ + size_t orig_d_stride = 0; /* Original destination stride (used for error handling) */ + size_t orig_nelmts = nelmts; /* Original # of elements to convert (used for error handling) */ + bool convert_forward = + true; /* Current direction of conversion (forward or backward, used for error handling) */ + bool conversions_made = + false; /* Flag to indicate conversions have been performed, used for error handling */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch (cdata->command) { + case H5T_CONV_INIT: + /* + * First, determine if this conversion function applies to the + * conversion path SRC_ID-->DST_ID. If not, return failure; + * otherwise initialize the `priv' field of `cdata' with + * information that remains (almost) constant for this + * conversion path. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype"); + if (H5T_VLEN != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype"); + if (H5T_VLEN != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype"); + if (H5T_VLEN_STRING == src->shared->u.vlen.type && H5T_VLEN_STRING == dst->shared->u.vlen.type) { + if ((H5T_CSET_ASCII == src->shared->u.vlen.cset && + H5T_CSET_UTF8 == dst->shared->u.vlen.cset) || + (H5T_CSET_ASCII == dst->shared->u.vlen.cset && H5T_CSET_UTF8 == src->shared->u.vlen.cset)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "The library doesn't convert between strings of ASCII and UTF"); + } /* end if */ + + /* Variable-length types don't need a background buffer */ + cdata->need_bkg = H5T_BKG_NO; + + break; + + case H5T_CONV_FREE: + /* QAK - Nothing to do currently */ + break; + + case H5T_CONV_CONV: + /* + * Conversion. + */ + if (NULL == src || NULL == dst) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if (NULL == conv_ctx) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid datatype conversion context pointer"); + + /* Initialize temporary conversion context */ + tmp_conv_ctx = *conv_ctx; + + /* Initialize source & destination strides */ + if (buf_stride) { + assert(buf_stride >= src->shared->size); + assert(buf_stride >= dst->shared->size); + H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); + s_stride = d_stride = (ssize_t)buf_stride; + } /* end if */ + else { + H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); + H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); + s_stride = (ssize_t)src->shared->size; + d_stride = (ssize_t)dst->shared->size; + } /* end else */ + if (bkg) { + if (bkg_stride) + b_stride = (ssize_t)bkg_stride; + else + b_stride = d_stride; + } /* end if */ + else + b_stride = 0; + + /* Get the size of the base types in src & dst */ + src_base_size = H5T_get_size(src->shared->parent); + dst_base_size = H5T_get_size(dst->shared->parent); + + /* Set up conversion path for base elements */ + if (NULL == (tpath = H5T_path_find(src->shared->parent, dst->shared->parent))) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unable to convert between src and dest datatypes"); + else if (!H5T_path_noop(tpath)) { + if (NULL == (tsrc_cpy = H5T_copy(src->shared->parent, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, + "unable to copy src base type for conversion"); + /* References need to know about the src file */ + if (tsrc_cpy->shared->type == H5T_REFERENCE) + if (H5T_set_loc(tsrc_cpy, src->shared->u.vlen.file, src->shared->u.vlen.loc) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set datatype location"); + + if (NULL == (tdst_cpy = H5T_copy(dst->shared->parent, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, + "unable to copy dst base type for conversion"); + /* References need to know about the dst file */ + if (tdst_cpy->shared->type == H5T_REFERENCE) + if (H5T_set_loc(tdst_cpy, dst->shared->u.vlen.file, dst->shared->u.vlen.loc) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set datatype location"); + + /* Create IDs for the variable-length base datatypes if the conversion path + * uses an application conversion function or if a conversion exception function + * was provided. + */ + if (tpath->conv.is_app || conv_ctx->u.conv.cb_struct.func) { + if ((tsrc_id = H5I_register(H5I_DATATYPE, tsrc_cpy, false)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "unable to register ID for source base datatype"); + if ((tdst_id = H5I_register(H5I_DATATYPE, tdst_cpy, false)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "unable to register ID for destination base datatype"); + } + + /* Update IDs in conversion context */ + tmp_conv_ctx.u.conv.src_type_id = tsrc_id; + tmp_conv_ctx.u.conv.dst_type_id = tdst_id; + } /* end else-if */ + else + noop_conv = true; + + /* Check if we need a temporary buffer for this conversion */ + if ((parent_is_vlen = H5T_detect_class(dst->shared->parent, H5T_VLEN, false)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_SYSTEM, FAIL, + "internal error when detecting variable-length class"); + if (tpath->cdata.need_bkg || parent_is_vlen) { + /* Set up initial background buffer */ + tmp_buf_size = MAX(src_base_size, dst_base_size); + if (NULL == (tmp_buf = H5FL_BLK_CALLOC(vlen_seq, tmp_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "memory allocation failed for type conversion"); + } /* end if */ + + /* Get the allocation info */ + if (H5CX_get_vlen_alloc_info(&vl_alloc_info) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info"); + + /* Set flags to indicate we are writing to or reading from the file */ + if (dst->shared->u.vlen.file != NULL) + write_to_file = true; + + /* Set the flag for nested VL case */ + if (write_to_file && parent_is_vlen && bkg != NULL) + nested = true; + + /* Save info for unraveling on errors */ + orig_d_stride = (size_t)d_stride; + convert_forward = !(d_stride > s_stride); + + /* The outer loop of the type conversion macro, controlling which */ + /* direction the buffer is walked */ + while (nelmts > 0) { + /* Check if we need to go backwards through the buffer */ + if (d_stride > s_stride) { + /* Sanity check */ + assert(s_stride > 0); + assert(d_stride > 0); + assert(b_stride >= 0); + + /* Compute the number of "safe" destination elements at */ + /* the end of the buffer (Those which don't overlap with */ + /* any source elements at the beginning of the buffer) */ + safe = + nelmts - (((nelmts * (size_t)s_stride) + ((size_t)d_stride - 1)) / (size_t)d_stride); + + /* If we're down to the last few elements, just wrap up */ + /* with a "real" reverse copy */ + if (safe < 2) { + s = (uint8_t *)buf + (nelmts - 1) * (size_t)s_stride; + d = (uint8_t *)buf + (nelmts - 1) * (size_t)d_stride; + if (bkg) + b = (uint8_t *)bkg + (nelmts - 1) * (size_t)b_stride; + s_stride = -s_stride; + d_stride = -d_stride; + b_stride = -b_stride; + + safe = nelmts; + } /* end if */ + else { + s = (uint8_t *)buf + (nelmts - safe) * (size_t)s_stride; + d = (uint8_t *)buf + (nelmts - safe) * (size_t)d_stride; + if (bkg) + b = (uint8_t *)bkg + (nelmts - safe) * (size_t)b_stride; + } /* end else */ + } /* end if */ + else { + /* Single forward pass over all data */ + s = d = (uint8_t *)buf; + b = (uint8_t *)bkg; + safe = nelmts; + } /* end else */ + + for (elmtno = 0; elmtno < safe; elmtno++) { + bool is_nil; /* Whether sequence is "nil" */ + + /* Check for "nil" source sequence */ + if ((*(src->shared->u.vlen.cls->isnull))(src->shared->u.vlen.file, s, &is_nil) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't check if VL data is 'nil'"); + else if (is_nil) { + /* Write "nil" sequence to destination location */ + if ((*(dst->shared->u.vlen.cls->setnull))(dst->shared->u.vlen.file, d, b) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't set VL data to 'nil'"); + } /* end else-if */ + else { + size_t seq_len; /* The number of elements in the current sequence */ + + /* Get length of element sequences */ + if ((*(src->shared->u.vlen.cls->getlen))(src->shared->u.vlen.file, s, &seq_len) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "bad sequence length"); + + /* If we are reading from memory and there is no conversion, just get the pointer to + * sequence */ + if (write_to_file && noop_conv) { + /* Get direct pointer to sequence */ + if (NULL == (conv_buf = (*(src->shared->u.vlen.cls->getptr))(s))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid source pointer"); + } /* end if */ + else { + size_t src_size, dst_size; /*source & destination total size in bytes*/ + + src_size = seq_len * src_base_size; + dst_size = seq_len * dst_base_size; + + /* Check if conversion buffer is large enough, resize if + * necessary. If the SEQ_LEN is 0, allocate a minimal size buffer. + */ + if (!seq_len && !conv_buf) { + conv_buf_size = H5T_VLEN_MIN_CONF_BUF_SIZE; + if (NULL == (conv_buf = H5FL_BLK_CALLOC(vlen_seq, conv_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + } /* end if */ + else if (conv_buf_size < MAX(src_size, dst_size)) { + /* Only allocate conversion buffer in H5T_VLEN_MIN_CONF_BUF_SIZE increments */ + conv_buf_size = ((MAX(src_size, dst_size) / H5T_VLEN_MIN_CONF_BUF_SIZE) + 1) * + H5T_VLEN_MIN_CONF_BUF_SIZE; + if (NULL == (conv_buf = H5FL_BLK_REALLOC(vlen_seq, conv_buf, conv_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + memset(conv_buf, 0, conv_buf_size); + } /* end else-if */ + + /* Read in VL sequence */ + if ((*(src->shared->u.vlen.cls->read))(src->shared->u.vlen.file, s, conv_buf, + src_size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data"); + } /* end else */ + + if (!noop_conv) { + /* Check if temporary buffer is large enough, resize if necessary */ + /* (Chain off the conversion buffer size) */ + if (tmp_buf && tmp_buf_size < conv_buf_size) { + /* Set up initial background buffer */ + tmp_buf_size = conv_buf_size; + if (NULL == (tmp_buf = H5FL_BLK_REALLOC(vlen_seq, tmp_buf, tmp_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + memset(tmp_buf, 0, tmp_buf_size); + } /* end if */ + + /* If we are writing and there is a nested VL type, read + * the sequence into the background buffer */ + if (nested) { + /* Sanity check */ + assert(write_to_file); + + /* Get length of background element sequence */ + if ((*(dst->shared->u.vlen.cls->getlen))(dst->shared->u.vlen.file, b, + &bg_seq_len) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "bad sequence length"); + + /* Read sequence if length > 0 */ + if (bg_seq_len > 0) { + if (tmp_buf_size < (bg_seq_len * MAX(src_base_size, dst_base_size))) { + tmp_buf_size = (bg_seq_len * MAX(src_base_size, dst_base_size)); + if (NULL == + (tmp_buf = H5FL_BLK_REALLOC(vlen_seq, tmp_buf, tmp_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + memset(tmp_buf, 0, tmp_buf_size); + } /* end if */ + + /* Read in background VL sequence */ + if ((*(dst->shared->u.vlen.cls->read))(dst->shared->u.vlen.file, b, + tmp_buf, + bg_seq_len * dst_base_size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data"); + } /* end if */ + + /* If the sequence gets shorter, pad out the original sequence with zeros */ + if (bg_seq_len < seq_len) + memset((uint8_t *)tmp_buf + dst_base_size * bg_seq_len, 0, + (seq_len - bg_seq_len) * dst_base_size); + } /* end if */ + + /* Convert VL sequence */ + tmp_conv_ctx.u.conv.recursive = true; + if (H5T_convert_with_ctx(tpath, tsrc_cpy, tdst_cpy, &tmp_conv_ctx, seq_len, + (size_t)0, (size_t)0, conv_buf, tmp_buf) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, + "datatype conversion failed"); + tmp_conv_ctx.u.conv.recursive = false; + } /* end if */ + + /* Write sequence to destination location */ + if ((*(dst->shared->u.vlen.cls->write))(dst->shared->u.vlen.file, &vl_alloc_info, d, + conv_buf, b, seq_len, dst_base_size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data"); + + if (!noop_conv) { + /* For nested VL case, free leftover heap objects from the deeper level if the + * length of new data elements is shorter than the old data elements.*/ + if (nested && seq_len < bg_seq_len) { + uint8_t *tmp; + size_t u; + + /* Sanity check */ + assert(write_to_file); + + tmp = (uint8_t *)tmp_buf + seq_len * dst_base_size; + for (u = seq_len; u < bg_seq_len; u++, tmp += dst_base_size) { + /* Recursively free destination data */ + if (H5T__conv_vlen_nested_free(tmp, dst->shared->parent) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, + "unable to remove heap object"); + } /* end for */ + } /* end if */ + } /* end if */ + } /* end else */ + + /* Indicate that elements have been converted, in case of error */ + conversions_made = true; + + /* Advance pointers */ + s += s_stride; + d += d_stride; + + if (b) + b += b_stride; + } /* end for */ + + /* Decrement number of elements left to convert */ + nelmts -= safe; + } /* end while */ + + break; + + default: /* Some other command we don't know about yet.*/ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); + } /* end switch */ + +done: + /* Release converted elements on error */ + if (ret_value < 0 && conversions_made) { + size_t dest_count; + + /* Set up for first pass to destroy references */ + if (nelmts < orig_nelmts || (convert_forward && elmtno < safe)) { + dest_count = orig_nelmts - nelmts; + + /* Set pointer to correct location, based on direction chosen */ + if (convert_forward) { + d = (uint8_t *)buf; + dest_count += elmtno; /* Include partial iteration in first pass, for forward conversions */ + } + else + d = (uint8_t *)buf + (nelmts * orig_d_stride); + + /* Destroy vlen elements that have already been converted */ + while (dest_count > 0) { + H5T_vlen_reclaim_elmt(d, dst); /* Ignore errors at this point */ + d += orig_d_stride; + dest_count--; + } + } + + /* Do any remaining partial iteration, if converting backwards */ + if (!convert_forward && elmtno < safe) { + dest_count = elmtno; + + /* Set pointer to correct location */ + if (d_stride > 0) + d = (uint8_t *)buf + ((nelmts - safe) * orig_d_stride); + else + d = (uint8_t *)buf + ((nelmts - elmtno) * orig_d_stride); + + /* Destroy references that have already been converted */ + while (dest_count > 0) { + H5T_vlen_reclaim_elmt(d, dst); /* Ignore errors at this point */ + d += orig_d_stride; + dest_count--; + } + } + } + + if (tsrc_id >= 0) { + if (H5I_dec_ref(tsrc_id) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); + } + else if (tsrc_cpy) { + if (H5T_close(tsrc_cpy) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); + } + if (tdst_id >= 0) { + if (H5I_dec_ref(tdst_id) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); + } + else if (tdst_cpy) { + if (H5T_close(tdst_cpy) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); + } + + /* If the conversion buffer doesn't need to be freed, reset its pointer */ + if (write_to_file && noop_conv) + conv_buf = NULL; + /* Release the conversion buffer (always allocated, except on errors) */ + if (conv_buf) + conv_buf = H5FL_BLK_FREE(vlen_seq, conv_buf); + /* Release the background buffer, if we have one */ + if (tmp_buf) + tmp_buf = H5FL_BLK_FREE(vlen_seq, tmp_buf); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_vlen() */ diff --git a/src/H5Tconv_vlen.h b/src/H5Tconv_vlen.h new file mode 100644 index 00000000000..a6a38d82ef1 --- /dev/null +++ b/src/H5Tconv_vlen.h @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef H5Tconv_vlen_H +#define H5Tconv_vlen_H + +/* Private headers needed by this file */ +#include "H5Tpkg.h" + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/****************************************/ +/* Soft (emulated) conversion functions */ +/****************************************/ + +/* Conversion functions between variable-length datatypes */ +H5_DLL herr_t H5T__conv_vlen(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, + const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); + +/*********************************************/ +/* Hard (compiler cast) conversion functions */ +/*********************************************/ + +#endif /* H5Tconv_vlen_H */ diff --git a/src/H5Tdbg.c b/src/H5Tdbg.c index 49c9d0f5dbf..b1de7708b8f 100644 --- a/src/H5Tdbg.c +++ b/src/H5Tdbg.c @@ -61,7 +61,7 @@ /*******************/ /*------------------------------------------------------------------------- - * Function: H5T__print_stats + * Function: H5T__print_path_stats * * Purpose: Print statistics about a conversion path. Statistics are * printed only if all the following conditions are true: @@ -80,7 +80,7 @@ *------------------------------------------------------------------------- */ herr_t -H5T__print_stats(H5T_path_t H5_ATTR_UNUSED *path, int H5_ATTR_UNUSED *nprint /*in,out*/) +H5T__print_path_stats(H5T_path_t H5_ATTR_UNUSED *path, int H5_ATTR_UNUSED *nprint /*in,out*/) { FUNC_ENTER_PACKAGE_NOERR @@ -124,7 +124,7 @@ H5T__print_stats(H5T_path_t H5_ATTR_UNUSED *path, int H5_ATTR_UNUSED *nprint /*i #endif FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5T__print_stats() */ +} /* end H5T__print_path_stats() */ /*------------------------------------------------------------------------- * Function: H5T_debug diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 8eb7b639cf0..8ceea058592 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -41,9 +41,6 @@ /* Other public headers needed by this file */ #include "H5Spublic.h" /* Dataspace functions */ -/* Length of debugging name buffer */ -#define H5T_NAMELEN 32 - /* Macro to ease detecting "complex" datatypes (i.e. those with base types or fields) */ #define H5T_IS_COMPLEX(t) \ ((t) == H5T_COMPOUND || (t) == H5T_ENUM || (t) == H5T_VLEN || (t) == H5T_ARRAY || (t) == H5T_REFERENCE) @@ -151,85 +148,6 @@ #endif #endif -/* Statistics about a conversion function */ -struct H5T_stats_t { - unsigned ncalls; /*num calls to conversion function */ - hsize_t nelmts; /*total data points converted */ - H5_timevals_t times; /*total time for conversion */ -}; - -/* Context struct for information used during datatype conversions. - * Which union member is valid to read from is dictated by the - * accompanying H5T_cdata_t structure's H5T_cmd_t member value. - */ -typedef struct H5T_conv_ctx_t { - union { - /* - * Fields only valid during conversion function initialization - * (H5T_cmd_t H5T_CONV_INIT) - */ - struct H5T_conv_ctx_init_fields { - H5T_conv_cb_t cb_struct; - } init; - - /* - * Fields only valid during conversion function conversion - * process (H5T_cmd_t H5T_CONV_CONV) - */ - struct H5T_conv_ctx_conv_fields { - H5T_conv_cb_t cb_struct; - hid_t dxpl_id; - hid_t src_type_id; - hid_t dst_type_id; - - /* Is conversion currently being done on a member of - * a container type, like a compound datatype? If so, - * cached information can be reused rather than creating - * and tearing it down for every compound element. - */ - bool recursive; - } conv; - - /* - * Fields only valid during conversion function free process - * (H5T_cmd_t H5T_CONV_FREE) - */ - struct H5T_conv_ctx_free_fields { - hid_t src_type_id; - hid_t dst_type_id; - } free; - } u; -} H5T_conv_ctx_t; - -/* Library internal datatype conversion functions are... */ -typedef herr_t (*H5T_lib_conv_t)(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); - -/* Conversion callbacks */ -typedef struct H5T_conv_func_t { - bool is_app; /* Whether conversion function is registered from application */ - union { - H5T_conv_t app_func; /* Application data conversion function */ - H5T_lib_conv_t lib_func; /* Library internal data conversion function */ - } u; -} H5T_conv_func_t; - -/* The datatype conversion database */ -struct H5T_path_t { - char name[H5T_NAMELEN]; /*name for debugging only */ - H5T_t *src; /*source datatype */ - H5T_t *dst; /*destination datatype */ - H5T_conv_func_t conv; /* Conversion function */ - bool is_hard; /*is it a hard function? */ - bool is_noop; /*is it the noop conversion? */ - H5T_cdata_t cdata; /*data for this function */ - -#ifdef H5T_DEBUG - H5T_stats_t stats; /*statistics for the conversion */ -#endif -}; - /* Reference function pointers */ typedef herr_t (*H5T_ref_isnullfunc_t)(const H5VL_object_t *file, const void *src_buf, bool *isnull); typedef herr_t (*H5T_ref_setnullfunc_t)(H5VL_object_t *file, void *dst_buf, void *bg_buf); @@ -410,14 +328,6 @@ struct H5T_t { H5VL_object_t *vol_obj; /* pointer to VOL object when working with committed datatypes */ }; -/* The master list of soft conversion functions */ -typedef struct H5T_soft_t { - char name[H5T_NAMELEN]; /*name for debugging only */ - H5T_class_t src; /*source datatype class */ - H5T_class_t dst; /*destination datatype class */ - H5T_conv_func_t conv; /*the conversion function */ -} H5T_soft_t; - /* Bit search direction */ typedef enum H5T_sdir_t { H5T_BIT_LSB, /*search lsb toward msb */ @@ -538,618 +448,6 @@ H5_DLL herr_t H5T__commit_named(const H5G_loc_t *loc, const char *name, H5T_t *d H5_DLL H5T_t *H5T__open_name(const H5G_loc_t *loc, const char *name); H5_DLL hid_t H5T__get_create_plist(const H5T_t *type); -/* Helper function for H5T_convert that accepts a pointer to a H5T_conv_ctx_t structure */ -H5_DLL herr_t H5T_convert_with_ctx(H5T_path_t *tpath, const H5T_t *src_type, const H5T_t *dst_type, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); - -/* Conversion functions */ -H5_DLL herr_t H5T__conv_noop(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); - -H5_DLL herr_t H5T__conv_order(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); -H5_DLL herr_t H5T__conv_order_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); -H5_DLL herr_t H5T__conv_struct(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); -H5_DLL herr_t H5T__conv_struct_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); -H5_DLL herr_t H5T__conv_enum(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_enum_numeric(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_vlen(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_array(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ref(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_i_i(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); -H5_DLL herr_t H5T__conv_f_f(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); -H5_DLL herr_t H5T__conv_f_i(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); -H5_DLL herr_t H5T__conv_i_f(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); -H5_DLL herr_t H5T__conv_s_s(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); -H5_DLL herr_t H5T__conv_b_b(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *_buf, void *bkg); - -H5_DLL herr_t H5T__conv_schar_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); - -H5_DLL herr_t H5T__conv_short_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); - -H5_DLL herr_t H5T__conv_int_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); - -H5_DLL herr_t H5T__conv_long_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); - -H5_DLL herr_t H5T__conv_llong_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_schar_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_float(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_double(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong_ldouble(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_schar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_uchar(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_short(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_ushort(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_int(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_uint(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_long(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_ulong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_llong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ldouble_ullong(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); - -#ifdef H5_HAVE__FLOAT16 -H5_DLL herr_t H5T__conv_schar__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uchar__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_short__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ushort__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_int__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_uint__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_long__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ulong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_llong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_ullong__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_float__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv_double__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -#ifdef H5T_CONV_INTERNAL_LDOUBLE_FLOAT16 -H5_DLL herr_t H5T__conv_ldouble__Float16(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -#endif -H5_DLL herr_t H5T__conv__Float16_schar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_uchar(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_short(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_ushort(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_int(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_uint(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_long(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_ulong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_llong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_ullong(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_float(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_double(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T__conv__Float16_ldouble(const H5T_t *st, const H5T_t *dt, H5T_cdata_t *cdata, - const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride, - size_t bkg_stride, void *buf, void *bkg); -#endif - /* Bit twiddling functions */ H5_DLL void H5T__bit_copy(uint8_t *dst, size_t dst_offset, const uint8_t *src, size_t src_offset, size_t size); @@ -1178,10 +476,9 @@ H5_DLL herr_t H5T__ref_reclaim(void *elem, const H5T_t *dt); H5_DLL htri_t H5T__ref_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc); /* Compound functions */ -H5_DLL herr_t H5T__insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member); -H5_DLL size_t H5T__get_member_size(const H5T_t *dt, unsigned membno); -H5_DLL void H5T__update_packed(const H5T_t *dt); -H5_DLL H5T_subset_info_t *H5T__conv_struct_subset(const H5T_cdata_t *cdata); +H5_DLL herr_t H5T__insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member); +H5_DLL size_t H5T__get_member_size(const H5T_t *dt, unsigned membno); +H5_DLL void H5T__update_packed(const H5T_t *dt); /* Enumerated type functions */ H5_DLL H5T_t *H5T__enum_create(const H5T_t *parent); @@ -1193,10 +490,4 @@ H5_DLL char *H5T__get_member_name(H5T_t const *dt, unsigned membno) H5_ATTR_MAL H5_DLL herr_t H5T__sort_value(const H5T_t *dt, int *map); H5_DLL herr_t H5T__sort_name(const H5T_t *dt, int *map); -/* Debugging functions */ -H5_DLL herr_t H5T__print_stats(H5T_path_t *path, int *nprint /*in,out*/); - -/* Testing functions */ -H5_DLL int H5T__get_path_table_npaths(void); - #endif /* H5Tpkg_H */ diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 99ea256b27d..bf938ffb1bd 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -30,6 +30,7 @@ typedef struct H5T_t H5T_t; #include "H5private.h" /* Generic Functions */ #include "H5Gprivate.h" /* Groups */ #include "H5Rprivate.h" /* References */ +#include "H5Tconv.h" /* Datatype conversions */ #include "H5VLprivate.h" /* VOL Drivers */ /* Macro for size of temporary buffers to contain a single element */ @@ -50,10 +51,6 @@ typedef struct H5T_t H5T_t; #define H5T_GET_FORCE_CONV(T) (H5T_get_force_conv(T)) #endif /* H5T_MODULE */ -/* Forward references of package typedefs (declared in H5Tpkg.h) */ -typedef struct H5T_stats_t H5T_stats_t; -typedef struct H5T_path_t H5T_path_t; - /* Forward reference of H5S_t */ struct H5S_t; @@ -76,29 +73,6 @@ typedef struct { void *free_info; /* Free information */ } H5T_vlen_alloc_info_t; -/* Structure for conversion callback property */ -typedef struct H5T_conv_cb_t { - H5T_conv_except_func_t func; - void *user_data; -} H5T_conv_cb_t; - -/* Values for the optimization of compound data reading and writing. They indicate - * whether the fields of the source and destination are subset of each other and - * there is no conversion needed. - */ -typedef enum { - H5T_SUBSET_BADVALUE = -1, /* Invalid value */ - H5T_SUBSET_FALSE = 0, /* Source and destination aren't subset of each other */ - H5T_SUBSET_SRC, /* Source is the subset of dest and no conversion is needed */ - H5T_SUBSET_DST, /* Dest is the subset of source and no conversion is needed */ - H5T_SUBSET_CAP /* Must be the last value */ -} H5T_subset_t; - -typedef struct H5T_subset_info_t { - H5T_subset_t subset; /* See above */ - size_t copy_size; /* Size in bytes, to copy for each element */ -} H5T_subset_info_t; - /* Forward declarations for prototype arguments */ struct H5G_loc_t; struct H5G_name_t; @@ -118,7 +92,6 @@ H5_DLL H5T_t *H5T_get_super(const H5T_t *dt); H5_DLL H5T_class_t H5T_get_class(const H5T_t *dt, htri_t internal); H5_DLL htri_t H5T_detect_class(const H5T_t *dt, H5T_class_t cls, bool from_api); H5_DLL size_t H5T_get_size(const H5T_t *dt); -H5_DLL bool H5T_get_force_conv(const H5T_t *dt); H5_DLL int H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, bool superset); H5_DLL herr_t H5T_encode(H5T_t *obj, unsigned char *buf, size_t *nalloc); H5_DLL H5T_t *H5T_decode(size_t buf_size, const unsigned char *buf); @@ -129,33 +102,23 @@ H5_DLL htri_t H5T_is_immutable(const H5T_t *dt); H5_DLL htri_t H5T_is_named(const H5T_t *dt); H5_DLL herr_t H5T_convert_committed_datatype(H5T_t *dt, H5F_t *f); H5_DLL htri_t H5T_is_relocatable(const H5T_t *dt); -H5_DLL H5T_path_t *H5T_path_find(const H5T_t *src, const H5T_t *dst); -H5_DLL bool H5T_path_noop(const H5T_path_t *p); -H5_DLL bool H5T_noop_conv(const H5T_t *src, const H5T_t *dst); -H5_DLL H5T_bkg_t H5T_path_bkg(const H5T_path_t *p); -H5_DLL H5T_subset_info_t *H5T_path_compound_subset(const H5T_path_t *p); H5_DLL herr_t H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5VL_object_t *owned_vol_obj, H5T_conv_t func); -H5_DLL herr_t H5T_convert(H5T_path_t *tpath, const H5T_t *src_type, const H5T_t *dst_type, size_t nelmts, - size_t buf_stride, size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T_reclaim(const H5T_t *type, struct H5S_t *space, void *buf); -H5_DLL herr_t H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned ndim, const hsize_t *point, void *op_data); -H5_DLL herr_t H5T_vlen_reclaim_elmt(void *elem, const H5T_t *dt); -H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc); -H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); -H5_DLL uint32_t H5T_hash(H5F_t *file, const H5T_t *dt); -H5_DLL herr_t H5T_set_version(H5F_t *f, H5T_t *dt); -H5_DLL herr_t H5T_patch_file(H5T_t *dt, H5F_t *f); -H5_DLL herr_t H5T_patch_vlen_file(H5T_t *dt, H5VL_object_t *file); -H5_DLL herr_t H5T_own_vol_obj(H5T_t *dt, H5VL_object_t *vol_obj); -H5_DLL htri_t H5T_is_variable_str(const H5T_t *dt); -H5_DLL H5T_t *H5T_construct_datatype(H5VL_object_t *dt_obj); -H5_DLL H5VL_object_t *H5T_get_named_type(const H5T_t *dt); -H5_DLL H5T_t *H5T_get_actual_type(H5T_t *dt); -H5_DLL herr_t H5T_save_refresh_state(hid_t tid, struct H5O_shared_t *cached_H5O_shared); -H5_DLL herr_t H5T_restore_refresh_state(hid_t tid, struct H5O_shared_t *cached_H5O_shared); -H5_DLL bool H5T_already_vol_managed(const H5T_t *dt); -H5_DLL htri_t H5T_is_vl_storage(const H5T_t *dt); +H5_DLL herr_t H5T_vlen_reclaim_elmt(void *elem, const H5T_t *dt); +H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc); +H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); +H5_DLL herr_t H5T_set_version(H5F_t *f, H5T_t *dt); +H5_DLL herr_t H5T_patch_file(H5T_t *dt, H5F_t *f); +H5_DLL herr_t H5T_patch_vlen_file(H5T_t *dt, H5VL_object_t *file); +H5_DLL herr_t H5T_own_vol_obj(H5T_t *dt, H5VL_object_t *vol_obj); +H5_DLL htri_t H5T_is_variable_str(const H5T_t *dt); +H5_DLL H5T_t *H5T_construct_datatype(H5VL_object_t *dt_obj); +H5_DLL H5VL_object_t *H5T_get_named_type(const H5T_t *dt); +H5_DLL H5T_t *H5T_get_actual_type(H5T_t *dt); +H5_DLL herr_t H5T_save_refresh_state(hid_t tid, struct H5O_shared_t *cached_H5O_shared); +H5_DLL herr_t H5T_restore_refresh_state(hid_t tid, struct H5O_shared_t *cached_H5O_shared); +H5_DLL bool H5T_already_vol_managed(const H5T_t *dt); +H5_DLL htri_t H5T_is_vl_storage(const H5T_t *dt); H5_DLL herr_t H5T_invoke_vol_optional(H5T_t *dt, H5VL_optional_args_t *args, hid_t dxpl_id, void **req, H5VL_object_t **vol_obj_ptr); H5_DLL bool H5T_is_numeric_with_unusual_unused_bits(const H5T_t *dt); diff --git a/src/H5build_settings.autotools.c.in b/src/H5build_settings.autotools.c.in index edde377b43a..614fd1199b7 100644 --- a/src/H5build_settings.autotools.c.in +++ b/src/H5build_settings.autotools.c.in @@ -109,7 +109,6 @@ const char H5build_settings[]= " Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@\n" " API tracing: @TRACE_API@\n" " Using memory checker: @USINGMEMCHECKER@\n" - " Function stack tracing: @CODESTACK@\n" " Use file locking: @DESIRED_FILE_LOCKING@\n" " Strict file format checks: @STRICT_FORMAT_CHECKS@\n" " Optimization instrumentation: @INSTRUMENT_LIBRARY@\n" diff --git a/src/H5build_settings.cmake.c.in b/src/H5build_settings.cmake.c.in index c1139b465e6..8889ebf8d6f 100644 --- a/src/H5build_settings.cmake.c.in +++ b/src/H5build_settings.cmake.c.in @@ -108,7 +108,6 @@ const char H5build_settings[]= " Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@\n" " API tracing: @HDF5_ENABLE_TRACE@\n" " Using memory checker: @HDF5_ENABLE_USING_MEMCHECKER@\n" - " Function stack tracing: @HDF5_ENABLE_CODESTACK@\n" " Use file locking: @HDF5_FILE_LOCKING_SETTING@\n" " Strict file format checks: @HDF5_STRICT_FORMAT_CHECKS@\n" " Optimization instrumentation: @HDF5_Enable_Instrument@\n" diff --git a/src/H5private.h b/src/H5private.h index aa3297f1be5..5654fd900b7 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -160,13 +160,15 @@ #include "uthash.h" /* - * NT doesn't define SIGBUS, but since NT only runs on processors - * that do not have alignment constraints a SIGBUS would never be - * raised, so we just replace it with SIGILL (which also should - * never be raised by the hdf5 library). + * Does the compiler support the __builtin_expect() syntax? + * It's not a problem if not. */ -#ifndef SIGBUS -#define SIGBUS SIGILL +#if H5_HAVE_BUILTIN_EXPECT +#define H5_LIKELY(expression) __builtin_expect(!!(expression), 1) +#define H5_UNLIKELY(expression) __builtin_expect(!!(expression), 0) +#else +#define H5_LIKELY(expression) (expression) +#define H5_UNLIKELY(expression) (expression) #endif /* @@ -1235,18 +1237,6 @@ extern bool H5_libterm_g; /* Is the library being shutdown? */ #endif /* H5_HAVE_THREADSAFE */ -#ifdef H5_HAVE_CODESTACK - -/* Include required function stack header */ -#include "H5CSprivate.h" - -#define H5_PUSH_FUNC H5CS_push(__func__); -#define H5_POP_FUNC H5CS_pop(); -#else /* H5_HAVE_CODESTACK */ -#define H5_PUSH_FUNC /* void */ -#define H5_POP_FUNC /* void */ -#endif /* H5_HAVE_CODESTACK */ - /* Forward declaration of H5CXpush() / H5CXpop() */ /* (Including H5CXprivate.h creates bad circular dependencies - QAK, 3/18/2018) */ H5_DLL herr_t H5CX_push(void); @@ -1257,7 +1247,7 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); { \ static bool func_check = false; \ \ - if (!func_check) { \ + if (H5_UNLIKELY(!func_check)) { \ /* Check function naming status */ \ assert(asrt && \ "Function naming conventions are incorrect - check H5_IS_API|PUB|PRIV|PKG macros in " \ @@ -1293,17 +1283,14 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_ENTER_API_INIT(err) \ /* Initialize the library */ \ - if (!H5_INIT_GLOBAL && !H5_TERM_GLOBAL) { \ - if (H5_init_library() < 0) \ + if (H5_UNLIKELY(!H5_INIT_GLOBAL && !H5_TERM_GLOBAL)) { \ + if (H5_UNLIKELY(H5_init_library() < 0)) \ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, err, "library initialization failed"); \ } #define FUNC_ENTER_API_PUSH(err) \ - /* Push the name of this function on the function stack */ \ - H5_PUSH_FUNC \ - \ /* Push the API context */ \ - if (H5CX_push() < 0) \ + if (H5_UNLIKELY(H5CX_push() < 0)) \ HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, err, "can't set API context"); \ else \ api_ctx_pushed = true; @@ -1347,7 +1334,6 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); { \ { \ FUNC_ENTER_API_COMMON \ - H5_PUSH_FUNC \ { /* @@ -1404,14 +1390,12 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_ENTER_NOAPI(err) \ { \ FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ - H5_PUSH_FUNC \ { /* Use this macro for all non-API functions, which propagate errors, but don't issue them */ #define FUNC_ENTER_NOAPI_NOERR \ { \ FUNC_ENTER_COMMON_NOERR(!H5_IS_API(__func__)); \ - H5_PUSH_FUNC \ { /* @@ -1425,7 +1409,6 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_ENTER_NOAPI_NOINIT \ { \ FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ - H5_PUSH_FUNC \ { /* @@ -1438,33 +1421,6 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); * - functions that propagate, but don't issue errors */ #define FUNC_ENTER_NOAPI_NOINIT_NOERR \ - { \ - FUNC_ENTER_COMMON_NOERR(!H5_IS_API(__func__)); \ - H5_PUSH_FUNC \ - { - -/* - * Use this macro for non-API functions which fall into these categories: - * - functions which shouldn't push their name on the function stack - * (so far, just the H5CS routines themselves) - * - */ -#define FUNC_ENTER_NOAPI_NOFS \ - { \ - FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ - \ - { - -/* - * Use this macro for non-API functions which fall into these categories: - * - functions which shouldn't push their name on the function stack - * (so far, just the H5CS routines themselves) - * - * This macro is used for functions which fit the above categories _and_ - * also don't use the 'FUNC' variable (i.e. don't push errors on the error stack) - * - */ -#define FUNC_ENTER_NOAPI_NOERR_NOFS \ { \ FUNC_ENTER_COMMON_NOERR(!H5_IS_API(__func__)); \ { @@ -1489,7 +1445,6 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); \ FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ H5AC_tag(tag, &prev_tag); \ - H5_PUSH_FUNC \ { #define FUNC_ENTER_NOAPI_NOINIT_TAG(tag) \ @@ -1498,21 +1453,18 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); \ FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ H5AC_tag(tag, &prev_tag); \ - H5_PUSH_FUNC \ { /* Use this macro for all "normal" package-level functions */ #define FUNC_ENTER_PACKAGE \ { \ FUNC_ENTER_COMMON(H5_IS_PKG(__func__)); \ - H5_PUSH_FUNC \ { /* Use this macro for package-level functions which propagate errors, but don't issue them */ #define FUNC_ENTER_PACKAGE_NOERR \ { \ FUNC_ENTER_COMMON_NOERR(H5_IS_PKG(__func__)); \ - H5_PUSH_FUNC \ { /* Use the following macro as replacement for the FUNC_ENTER_PACKAGE @@ -1523,7 +1475,6 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); \ FUNC_ENTER_COMMON(H5_IS_PKG(__func__)); \ H5AC_tag(tag, &prev_tag); \ - H5_PUSH_FUNC \ { /* Use this macro for staticly-scoped functions which propagate errors, but don't issue them */ @@ -1557,13 +1508,12 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_LEAVE_API(ret_value) \ ; \ } /*end scope from end of FUNC_ENTER*/ \ - if (api_ctx_pushed) { \ + if (H5_LIKELY(api_ctx_pushed)) { \ (void)H5CX_pop(true); \ api_ctx_pushed = false; \ } \ - H5_POP_FUNC \ - if (err_occurred) \ - (void)H5E_dump_api_stack(true); \ + if (H5_UNLIKELY(err_occurred)) \ + (void)H5E_dump_api_stack(); \ FUNC_LEAVE_API_THREADSAFE \ return (ret_value); \ } \ @@ -1573,9 +1523,8 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_LEAVE_API_NOINIT(ret_value) \ ; \ } /*end scope from end of FUNC_ENTER*/ \ - H5_POP_FUNC \ - if (err_occurred) \ - (void)H5E_dump_api_stack(true); \ + if (H5_UNLIKELY(err_occurred)) \ + (void)H5E_dump_api_stack(); \ FUNC_LEAVE_API_THREADSAFE \ return (ret_value); \ } \ @@ -1597,8 +1546,8 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_LEAVE_API_NOPUSH(ret_value) \ ; \ } /*end scope from end of FUNC_ENTER*/ \ - if (err_occurred) \ - (void)H5E_dump_api_stack(true); \ + if (H5_UNLIKELY(err_occurred)) \ + (void)H5E_dump_api_stack(); \ FUNC_LEAVE_API_THREADSAFE \ return (ret_value); \ } \ @@ -1622,28 +1571,15 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_LEAVE_NOAPI(ret_value) \ ; \ } /*end scope from end of FUNC_ENTER*/ \ - H5_POP_FUNC \ return (ret_value); \ } /*end scope from beginning of FUNC_ENTER*/ #define FUNC_LEAVE_NOAPI_VOID \ ; \ } /*end scope from end of FUNC_ENTER*/ \ - H5_POP_FUNC \ return; \ } /*end scope from beginning of FUNC_ENTER*/ -/* - * Use this macro for non-API functions which fall into these categories: - * - functions which didn't push their name on the function stack - * (so far, just the H5CS routines themselves) - */ -#define FUNC_LEAVE_NOAPI_NOFS(ret_value) \ - ; \ - } /*end scope from end of FUNC_ENTER*/ \ - return (ret_value); \ - } /*end scope from beginning of FUNC_ENTER*/ - /* Use these macros to match the FUNC_ENTER_NOAPI_NAMECHECK_ONLY macro */ #define FUNC_LEAVE_NOAPI_NAMECHECK_ONLY(ret_value) \ return (ret_value); \ @@ -1657,7 +1593,6 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); ; \ } /*end scope from end of FUNC_ENTER*/ \ H5AC_tag(prev_tag, NULL); \ - H5_POP_FUNC \ return (ret_value); \ } /*end scope from beginning of FUNC_ENTER*/ diff --git a/src/Makefile.am b/src/Makefile.am index e6625777712..29706101001 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,7 +38,6 @@ libhdf5_la_SOURCES= H5.c H5build_settings.c H5checksum.c H5dbg.c H5system.c \ H5C.c H5Cdbg.c H5Centry.c H5Cepoch.c H5Cimage.c H5Cint.c \ H5Clog.c H5Clog_json.c H5Clog_trace.c \ H5Cprefetched.c H5Cquery.c H5Ctag.c H5Ctest.c \ - H5CS.c \ H5CX.c \ H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c \ H5Ddbg.c H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c \ @@ -92,6 +91,8 @@ libhdf5_la_SOURCES= H5.c H5build_settings.c H5checksum.c H5dbg.c H5system.c \ H5SL.c \ H5SM.c H5SMbtree2.c H5SMcache.c H5SMmessage.c H5SMtest.c \ H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c H5Tcompound.c H5Tconv.c \ + H5Tconv_integer.c H5Tconv_float.c H5Tconv_string.c H5Tconv_bitfield.c \ + H5Tconv_compound.c H5Tconv_reference.c H5Tconv_enum.c H5Tconv_vlen.c H5Tconv_array.c \ H5Tcset.c H5Tdbg.c H5Tdeprec.c H5Tenum.c H5Tfields.c H5Tfixed.c \ H5Tfloat.c H5Tinit_float.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \ H5Torder.c H5Tref.c H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c \ diff --git a/src/libhdf5.settings.in b/src/libhdf5.settings.in index 87219969bf3..3854d72e411 100644 --- a/src/libhdf5.settings.in +++ b/src/libhdf5.settings.in @@ -90,7 +90,6 @@ Dimension scales w/ new references: @DIMENSION_SCALES_WITH_NEW_REF@ Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@ API tracing: @TRACE_API@ Using memory checker: @USINGMEMCHECKER@ - Function stack tracing: @CODESTACK@ Use file locking: @DESIRED_FILE_LOCKING@ Strict file format checks: @STRICT_FORMAT_CHECKS@ Optimization instrumentation: @INSTRUMENT_LIBRARY@ diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index 383ed7f1b5a..ed26b5459dc 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -15,6 +15,7 @@ #define H5T_FRIEND /*suppress error about including H5Tpkg */ #include "H5Tpkg.h" /*to turn off hardware conversions*/ +#include "H5Tconv_compound.h" #include "H5Iprivate.h" #include "h5test.h" diff --git a/test/h5test.c b/test/h5test.c index 064e6407907..be3b246ebbb 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -1116,11 +1116,15 @@ h5_show_hostname(void) MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); printf("MPI-process %d.", mpi_rank); } +#ifdef H5_HAVE_THREADSAFE else - printf("thread 0."); + printf("thread %" PRIu64 ".", H5TS_thread_id()); +#endif #else +#ifdef H5_HAVE_THREADSAFE printf("thread %" PRIu64 ".", H5TS_thread_id()); #endif +#endif #ifdef H5_HAVE_WIN32_API err = WSAStartup(MAKEWORD(2, 2), &wsaData); diff --git a/test/test_error.sh.in b/test/test_error.sh.in index 1e6a5603a6d..3657a7c1ad1 100644 --- a/test/test_error.sh.in +++ b/test/test_error.sh.in @@ -70,7 +70,7 @@ TEST() { fi # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ + sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ diff --git a/test/testfiles/err_compat_1 b/test/testfiles/err_compat_1 index e0c465431cb..fa02bcd1039 100644 --- a/test/testfiles/err_compat_1 +++ b/test/testfiles/err_compat_1 @@ -3,7 +3,7 @@ Testing error API based on data I/O All error API tests passed. This program tests the Error API compatible with HDF5 version (number). There are supposed to be some error messages ********* Print error stack in HDF5 default way ********* -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in main(): fake error message 1 major: Error API minor: Bad value @@ -12,7 +12,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): error #000: (file name) in main(): line (number) major: Error API minor: Bad value -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5Dcreate2(): unable to synchronously create dataset major: Dataset minor: Unable to create file @@ -70,7 +70,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): error #003: (file name) in H5Dcreate2(): line (number) major: Dataset minor: Unable to create file -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5Dcreate2(): unable to synchronously create dataset major: Dataset minor: Unable to create file @@ -83,7 +83,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #003: (file name) line (number) in H5VL_vol_object(): invalid identifier type to function major: Invalid arguments to routine minor: Inappropriate type -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in main(): fake error message 2 major: Error API minor: Unrecognized message diff --git a/test/testfiles/error_test_1 b/test/testfiles/error_test_1 index 9798facb96b..6d94d434e49 100644 --- a/test/testfiles/error_test_1 +++ b/test/testfiles/error_test_1 @@ -1,10 +1,10 @@ This program tests the Error API. There're supposed to be some error messages ********* Print error stack in HDF5 default way ********* -Second Test-DIAG: Error detected in Second Program (1.0) thread (IDs): +Second Test-DIAG: Error detected in Second Program (1.0): #000: (file name) line (number) in main(): Error stack test failed major: Error in test minor: Error in error stack -Error Test-DIAG: Error detected in Error Program (1.0) thread (IDs): +Error Test-DIAG: Error detected in Error Program (1.0): #001: (file name) line (number) in error_stack(): Get number test failed, returned 0 major: Error in API minor: Error in H5Eget_num @@ -20,21 +20,21 @@ Error Test-DIAG: Error detected in Error Program (1.0) thread (IDs): minor: Error in error stack Testing error API based on data I/O -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5Dwrite(): can't synchronously write data major: Dataset minor: Write failed #001: (file name) line (number) in H5D__write_api_common(): dset_id is not a dataset ID major: Invalid arguments to routine minor: Inappropriate type -Error Test-DIAG: Error detected in Error Program (1.0) thread (IDs): +Error Test-DIAG: Error detected in Error Program (1.0): #000: (file name) line (number) in main(): Error test failed, it's wrong major: Error in test minor: Error in subroutine #001: (file name) line (number) in test_error(): H5Dwrite failed as supposed to major: Error in IO minor: Error in H5Dwrite -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #002: (file name) line (number) in H5Dwrite(): can't synchronously write data major: Dataset minor: Write failed @@ -43,7 +43,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): minor: Inappropriate type Testing error message during data reading when filter isn't registered -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5Dread(): can't synchronously read data major: Dataset minor: Read failed diff --git a/test/trefer.c b/test/trefer.c index fc0d8942045..5fb78730a80 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -106,6 +106,7 @@ test_reference_params(void) ssize_t name_size; /* Size of reference name */ bool vol_is_native; herr_t ret; /* Generic return value */ + htri_t is_equal; /* Output message about test being performed */ MESSAGE(5, ("Testing Reference Parameters\n")); @@ -307,16 +308,16 @@ test_reference_params(void) /* Test parameters to H5Requal */ H5E_BEGIN_TRY { - ret = H5Requal(NULL, &rbuf[0]); + is_equal = H5Requal(NULL, &rbuf[0]); } H5E_END_TRY - VERIFY(ret, FAIL, "H5Requal ref1"); + VERIFY(is_equal, FAIL, "H5Requal ref1"); H5E_BEGIN_TRY { - ret = H5Requal(&rbuf[0], NULL); + is_equal = H5Requal(&rbuf[0], NULL); } H5E_END_TRY - VERIFY(ret, FAIL, "H5Requal ref2"); + VERIFY(is_equal, FAIL, "H5Requal ref2"); /* Test parameters to H5Rcopy */ H5E_BEGIN_TRY @@ -440,10 +441,13 @@ test_reference_obj(void) hid_t dapl_id; /* Dataset access property list */ H5R_ref_t *wbuf, /* buffer to write to disk */ *rbuf; /* buffer read from disk */ + H5R_ref_t *wbuf_cp; /* copy buffer */ unsigned *ibuf, *obuf; unsigned i, j; /* Counters */ H5O_type_t obj_type; /* Object type */ herr_t ret; /* Generic return value */ + ssize_t namelen; /* String buffer size return value */ + char buf[100]; /* Output message about test being performed */ MESSAGE(5, ("Testing Object Reference Functions\n")); @@ -551,6 +555,24 @@ test_reference_obj(void) CHECK(ret, FAIL, "H5Rget_obj_type3"); VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type3"); + /* Check copying a reference */ + wbuf_cp = calloc(sizeof(H5R_ref_t), 1); + ret = H5Rcopy(&wbuf[0], &wbuf_cp[0]); + CHECK(ret, FAIL, "H5Rcopy"); + + /* Check if references are equal */ + htri_t is_equal = H5Requal(&wbuf[0], &wbuf_cp[0]); + CHECK(is_equal, FAIL, "H5Requal"); + VERIFY(is_equal, TRUE, "H5Requal"); + + is_equal = H5Requal(&wbuf[0], &wbuf[2]); + CHECK(is_equal, FAIL, "H5Requal"); + VERIFY(is_equal, FALSE, "H5Requal"); + + ret = H5Rdestroy(&wbuf_cp[0]); + CHECK(ret, FAIL, "H5Rdestroy"); + free(wbuf_cp); + /* Write selection to disk */ ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); CHECK(ret, FAIL, "H5Dwrite"); @@ -579,6 +601,23 @@ test_reference_obj(void) ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); CHECK(ret, FAIL, "H5Dread"); + /* Check file name for reference */ + namelen = H5Rget_file_name(&rbuf[0], NULL, 0); + CHECK(namelen, FAIL, "H5Dget_file_name"); + VERIFY(namelen, strlen(FILE_REF_OBJ), "H5Dget_file_name"); + + /* Make sure size parameter is ignored */ + namelen = H5Rget_file_name(&rbuf[0], NULL, 200); + CHECK(namelen, FAIL, "H5Dget_file_name"); + VERIFY(namelen, strlen(FILE_REF_OBJ), "H5Dget_file_name"); + + /* Get the file name for the reference */ + namelen = H5Rget_file_name(&rbuf[0], (char *)buf, sizeof(buf)); + CHECK(namelen, FAIL, "H5Dget_file_name"); + + ret = !((strcmp(buf, FILE_REF_OBJ) == 0) && (namelen == strlen(FILE_REF_OBJ))); + CHECK(ret, FAIL, "H5Literate"); + /* Open dataset object */ dset2 = H5Ropen_object(&rbuf[0], H5P_DEFAULT, dapl_id); CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); diff --git a/testpar/t_vfd.c b/testpar/t_vfd.c index 93fa4992b55..3b924784ee3 100644 --- a/testpar/t_vfd.c +++ b/testpar/t_vfd.c @@ -4216,22 +4216,21 @@ static unsigned vector_write_test_8(int file_name_id, int mpi_rank, int mpi_size, H5FD_mpio_xfer_t xfer_mode, H5FD_mpio_collective_opt_t coll_opt_mode, const char *vfd_name) { - const char *fcn_name = "vector_write_test_8()"; - char test_title[120]; - char filename[512]; - haddr_t eoa; - haddr_t base_addr; - bool show_progress = false; - hid_t fapl_id = H5I_INVALID_HID; /* file access property list ID */ - hid_t dxpl_id = H5I_INVALID_HID; /* data access property list ID */ - H5FD_t *lf = NULL; /* VFD struct ptr */ - int cp = 0; - int i; - int base_index; - uint32_t count = 0; - size_t sizes[4]; - H5FD_mem_t types[2]; - + const char *fcn_name = "vector_write_test_8()"; + char test_title[120]; + char filename[512]; + haddr_t eoa; + haddr_t base_addr; + bool show_progress = false; + hid_t fapl_id = H5I_INVALID_HID; /* file access property list ID */ + hid_t dxpl_id = H5I_INVALID_HID; /* data access property list ID */ + H5FD_t *lf = NULL; /* VFD struct ptr */ + int cp = 0; + int i; + int base_index; + uint32_t count = 0; + size_t sizes[4]; + H5FD_mem_t types[2]; haddr_t *tt_addrs = NULL; /* For storing addrs */ const void **tt_bufs = NULL; /* For storing buf pointers */ @@ -4629,6 +4628,9 @@ test_vector_io(int mpi_rank, int mpi_size) H5FD_SUBFILING_NAME); #endif + /* discard the file image buffers */ + free_file_images(); + nerrors += (int)nerrs; /* return(nerrs);*/ @@ -5955,15 +5957,14 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H static void test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) { - hid_t mem_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* memory dataspaces vector */ - hid_t file_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* file dataspaces vector */ - hsize_t dims1[1]; /* 1d dimension sizes */ - hsize_t dims2[2]; /* 2d dimension sizes */ - - H5FD_mem_t type; /* File type */ - haddr_t addrs[2]; /* File allocation address */ - size_t element_sizes[2] = {sizeof(int), sizeof(int)}; /* Element size */ - size_t bufsize; /* Buffer size */ + hid_t mem_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* memory dataspaces vector */ + hid_t file_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* file dataspaces vector */ + hsize_t dims1[1]; /* 1d dimension sizes */ + hsize_t dims2[2]; /* 2d dimension sizes */ + H5FD_mem_t type; /* File type */ + haddr_t addrs[2]; /* File allocation address */ + size_t element_sizes[2] = {sizeof(int), sizeof(int)}; /* Element size */ + size_t bufsize; /* Buffer size */ int i; int j; @@ -6059,18 +6060,30 @@ test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) } /* Free the buffers */ - if (wbuf1) + if (wbuf1) { free(wbuf1); - if (wbuf2) + wbuf1 = NULL; + } + if (wbuf2) { free(wbuf2); - if (fbuf1) + wbuf2 = NULL; + } + if (fbuf1) { free(fbuf1); - if (fbuf2) + fbuf1 = NULL; + } + if (fbuf2) { free(fbuf2); - if (erbuf1) + fbuf2 = NULL; + } + if (erbuf1) { free(erbuf1); - if (erbuf2) + erbuf1 = NULL; + } + if (erbuf2) { free(erbuf2); + erbuf2 = NULL; + } CHECK_PASSED(); @@ -6085,11 +6098,10 @@ test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) static void test_selection_io(int mpi_rank, int mpi_size) { - H5FD_t *lf = NULL; /* VFD struct ptr */ - hid_t fapl = H5I_INVALID_HID; /* File access property list */ - char filename[1024]; /* Test file name */ - unsigned flags = 0; /* File access flags */ - + H5FD_t *lf = NULL; /* VFD struct ptr */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + char filename[1024]; /* Test file name */ + unsigned flags = 0; /* File access flags */ unsigned collective; /* Types of I/O for testing */ hid_t dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ hid_t def_dxpl = H5I_INVALID_HID; /* dxpl: independent access */ @@ -6309,9 +6321,6 @@ main(int argc, char **argv) printf("===================================\n"); } - /* discard the file image buffers */ - free_file_images(); - /* close HDF5 library */ H5close(); diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index bdbda6e74bc..9329872d965 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -16,6 +16,12 @@ #include "h5diff.h" #include "ph5diff.h" +#ifdef H5_HAVE_PARALLEL +static diff_err_t handle_worker_request(char *worker_tasks, int *n_busy_tasks, diff_opt_t *opts, + hsize_t *n_diffs); +static diff_err_t dispatch_diff_to_worker(struct diff_mpi_args *args, char *worker_tasks, int *n_busy_tasks); +#endif + /*------------------------------------------------------------------------- * Function: print_objname * @@ -91,35 +97,6 @@ phdiff_dismiss_workers(void) for (i = 1; i < g_nTasks; i++) MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD); } - -/*------------------------------------------------------------------------- - * Function: print_incoming_data - * - * Purpose: special function that prints any output that has been sent to the manager - * and is currently sitting in the incoming message queue - * - * Return: none - *------------------------------------------------------------------------- - */ - -static void -print_incoming_data(void) -{ - char data[PRINT_DATA_MAX_SIZE + 1]; - int incomingMessage; - MPI_Status Status; - - do { - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &incomingMessage, &Status); - if (incomingMessage) { - memset(data, 0, PRINT_DATA_MAX_SIZE + 1); - MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, - MPI_COMM_WORLD, &Status); - - parallel_print("%s", data); - } - } while (incomingMessage); -} #endif /*------------------------------------------------------------------------- @@ -992,24 +969,6 @@ h5diff(const char *fname1, const char *fname2, const char *objname1, const char } H5TOOLS_DEBUG("groups traversed - errstat:%d", opts->err_stat); -#ifdef H5_HAVE_PARALLEL - if (g_Parallel) { - int i; - - if ((strlen(fname1) > MAX_FILENAME) || (strlen(fname2) > MAX_FILENAME)) { - fprintf(stderr, "The parallel diff only supports path names up to %d characters\n", MAX_FILENAME); - MPI_Abort(MPI_COMM_WORLD, 0); - } /* end if */ - - strcpy(filenames[0], fname1); - strcpy(filenames[1], fname2); - - /* Alert the worker tasks that there's going to be work. */ - for (i = 1; i < g_nTasks; i++) - MPI_Send(filenames, (MAX_FILENAME * 2), MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD); - } /* end if */ -#endif - H5TOOLS_DEBUG("build_match_list next - errstat:%d", opts->err_stat); /* process the objects */ build_match_list(obj1fullname, info1_lp, obj2fullname, info2_lp, &match_list, opts); @@ -1042,6 +1001,24 @@ h5diff(const char *fname1, const char *fname2, const char *objname1, const char parallel_print("\n"); } /* end if */ } + +#ifdef H5_HAVE_PARALLEL + if (g_Parallel) { + if ((strlen(fname1) > MAX_FILENAME - 1) || (strlen(fname2) > MAX_FILENAME - 1)) { + fprintf(stderr, "The parallel diff only supports path names up to %d characters\n", + MAX_FILENAME - 1); + MPI_Abort(MPI_COMM_WORLD, 0); + } /* end if */ + + strcpy(filenames[0], fname1); + strcpy(filenames[1], fname2); + + /* Alert the worker tasks that there's going to be work. */ + for (int i = 1; i < g_nTasks; i++) + MPI_Send(filenames, (MAX_FILENAME * 2), MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD); + } /* end if */ +#endif + H5TOOLS_DEBUG("diff_match next - errstat:%d", opts->err_stat); nfound = diff_match(file1_id, obj1fullname, info1_lp, file2_id, obj2fullname, info2_lp, match_list, opts); H5TOOLS_DEBUG("diff_match nfound: %d - errstat:%d", nfound, opts->err_stat); @@ -1117,11 +1094,26 @@ diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1, hid_t file2_id, char *obj1_fullpath = NULL; char *obj2_fullpath = NULL; diff_args_t argdata; - size_t idx1 = 0; - size_t idx2 = 0; - diff_err_t ret_value = opts->err_stat; + size_t idx1 = 0; + size_t idx2 = 0; +#ifdef H5_HAVE_PARALLEL + char *workerTasks = NULL; + int busyTasks = 0; +#endif + diff_err_t ret_value = opts->err_stat; H5TOOLS_START_DEBUG(" - errstat:%d", opts->err_stat); + +#ifdef H5_HAVE_PARALLEL + if (g_Parallel) { + if (NULL == (workerTasks = malloc((size_t)(g_nTasks - 1) * sizeof(char)))) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "unable to allocate worker tasks array"); + + /*set all tasks as free */ + memset(workerTasks, 1, (size_t)(g_nTasks - 1) * sizeof(char)); + } +#endif + /* * if not root, prepare object name to be pre-appended to group path to * make full path @@ -1162,339 +1154,115 @@ diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1, hid_t file2_id, * do the diff for common objects *------------------------------------------------------------------------- */ -#ifdef H5_HAVE_PARALLEL - { - char *workerTasks = (char *)malloc((size_t)(g_nTasks - 1) * sizeof(char)); - int n; - int busyTasks = 0; - struct diffs_found nFoundbyWorker; - struct diff_mpi_args args; - int havePrintToken = 1; - MPI_Status Status; + for (i = 0; i < table->nobjs; i++) { + H5TOOLS_DEBUG("diff for common objects[%d] - errstat:%d", i, opts->err_stat); - /*set all tasks as free */ - memset(workerTasks, 1, (size_t)(g_nTasks - 1) * sizeof(char)); -#endif + /* Check if object is present in both files first before diffing */ + if (!(table->objs[i].flags[0] && table->objs[i].flags[1])) + continue; - for (i = 0; i < table->nobjs; i++) { - H5TOOLS_DEBUG("diff for common objects[%d] - errstat:%d", i, opts->err_stat); - if (table->objs[i].flags[0] && table->objs[i].flags[1]) { - /* make full path for obj1 */ + /* Make full paths for objects */ #ifdef H5_HAVE_ASPRINTF - /* Use the asprintf() routine, since it does what we're trying to do below */ - if (asprintf(&obj1_fullpath, "%s%s", grp1_path, table->objs[i].name) < 0) { - H5TOOLS_ERROR(H5DIFF_ERR, "name buffer allocation failed"); - } -#else /* H5_HAVE_ASPRINTF */ - if ((obj1_fullpath = (char *)malloc(strlen(grp1_path) + strlen(table->objs[i].name) + 1)) == - NULL) { - H5TOOLS_ERROR(H5DIFF_ERR, "name buffer allocation failed"); - } - else { - strcpy(obj1_fullpath, grp1_path); - strcat(obj1_fullpath, table->objs[i].name); - } -#endif /* H5_HAVE_ASPRINTF */ - H5TOOLS_DEBUG("diff_match path1 - %s", obj1_fullpath); + /* Use the asprintf() routine, since it does what we're trying to do below */ + if (asprintf(&obj1_fullpath, "%s%s", grp1_path, table->objs[i].name) < 0) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "name buffer allocation failed"); + if (asprintf(&obj2_fullpath, "%s%s", grp2_path, table->objs[i].name) < 0) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "name buffer allocation failed"); +#else + if (NULL == (obj1_fullpath = malloc(strlen(grp1_path) + strlen(table->objs[i].name) + 1))) + H5TOOLS_ERROR(H5DIFF_ERR, "name buffer allocation failed"); + else { + strcpy(obj1_fullpath, grp1_path); + strcat(obj1_fullpath, table->objs[i].name); + } + if (NULL == (obj2_fullpath = malloc(strlen(grp2_path) + strlen(table->objs[i].name) + 1))) + H5TOOLS_ERROR(H5DIFF_ERR, "name buffer allocation failed"); + else { + strcpy(obj2_fullpath, grp2_path); + strcat(obj2_fullpath, table->objs[i].name); + } +#endif - /* make full path for obj2 */ -#ifdef H5_HAVE_ASPRINTF - /* Use the asprintf() routine, since it does what we're trying to do below */ - if (asprintf(&obj2_fullpath, "%s%s", grp2_path, table->objs[i].name) < 0) { - H5TOOLS_ERROR(H5DIFF_ERR, "name buffer allocation failed"); - } -#else /* H5_HAVE_ASPRINTF */ - if ((obj2_fullpath = (char *)malloc(strlen(grp2_path) + strlen(table->objs[i].name) + 1)) == - NULL) { - H5TOOLS_ERROR(H5DIFF_ERR, "name buffer allocation failed"); - } - else { - strcpy(obj2_fullpath, grp2_path); - strcat(obj2_fullpath, table->objs[i].name); - } -#endif /* H5_HAVE_ASPRINTF */ - H5TOOLS_DEBUG("diff_match path2 - %s", obj2_fullpath); - - /* get index to figure out type of the object in file1 */ - while (info1->paths[idx1].path && (strcmp(obj1_fullpath, info1->paths[idx1].path) != 0)) - idx1++; - /* get index to figure out type of the object in file2 */ - while (info2->paths[idx2].path && (strcmp(obj2_fullpath, info2->paths[idx2].path) != 0)) - idx2++; - - /* Set argdata to pass other args into diff() */ - argdata.type[0] = info1->paths[idx1].type; - argdata.type[1] = info2->paths[idx2].type; - argdata.is_same_trgobj = table->objs[i].is_same_trgobj; - - opts->cmn_objs = 1; - if (!g_Parallel) { - H5TOOLS_DEBUG("diff paths - errstat:%d", opts->err_stat); - nfound += diff(file1_id, obj1_fullpath, file2_id, obj2_fullpath, opts, &argdata); - } /* end if */ -#ifdef H5_HAVE_PARALLEL - else { - int workerFound = 0; - - H5TOOLS_DEBUG("Beginning of big else block"); - /* We're in parallel mode */ - /* Since the data type of diff value is hsize_t which can - * be arbitrary large such that there is no MPI type that - * matches it, the value is passed between processes as - * an array of bytes in order to be portable. But this - * may not work in non-homogeneous MPI environments. - */ - - /*Set up args to pass to worker task. */ - if (strlen(obj1_fullpath) > 255 || strlen(obj2_fullpath) > 255) { - fprintf(stderr, - "The parallel diff only supports object names up to 255 characters\n"); - MPI_Abort(MPI_COMM_WORLD, 0); - } /* end if */ - - /* set args struct to pass */ - strcpy(args.name1, obj1_fullpath); - strcpy(args.name2, obj2_fullpath); - args.opts = *opts; - 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; - - /* if there are any outstanding print requests, let's handle one. */ - if (busyTasks > 0) { - int incomingMessage; - - /* check if any tasks freed up, and didn't need to print. */ - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &incomingMessage, &Status); - - /* first block*/ - if (incomingMessage) { - workerTasks[Status.MPI_SOURCE - 1] = 1; - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, - MPI_TAG_DONE, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker.nfound; - opts->not_cmp = opts->not_cmp | nFoundbyWorker.not_cmp; - busyTasks--; - } /* end if */ - - /* check to see if the print token was returned. */ - if (!havePrintToken) { - /* If we don't have the token, someone is probably sending us output */ - print_incoming_data(); - - /* check incoming queue for token */ - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, - &Status); - - /* incoming token implies free task. */ - if (incomingMessage) { - workerTasks[Status.MPI_SOURCE - 1] = 1; - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, - MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker.nfound; - opts->not_cmp = opts->not_cmp | nFoundbyWorker.not_cmp; - busyTasks--; - havePrintToken = 1; - } /* end if */ - } /* end if */ - - /* check to see if anyone needs the print token. */ - if (havePrintToken) { - /* check incoming queue for print token requests */ - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &incomingMessage, - &Status); - if (incomingMessage) { - MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, - MPI_COMM_WORLD, &Status); - MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, - MPI_COMM_WORLD); - havePrintToken = 0; - } /* end if */ - } /* end if */ - } /* end if */ - - /* check array of tasks to see which ones are free. - * Manager task never does work, so freeTasks[0] is really - * worker task 0. */ - for (n = 1; (n < g_nTasks) && !workerFound; n++) { - if (workerTasks[n - 1]) { - /* send file id's and names to first free worker */ - MPI_Send(&args, sizeof(args), MPI_BYTE, n, MPI_TAG_ARGS, MPI_COMM_WORLD); - - /* increment counter for total number of prints. */ - busyTasks++; - - /* mark worker as busy */ - workerTasks[n - 1] = 0; - workerFound = 1; - } /* end if */ - } /* end for */ - - if (!workerFound) { - /* if they were all busy, we've got to wait for one free up - * before we can move on. If we don't have the token, some - * task is currently printing so we'll wait for that task to - * return it. - */ - - if (!havePrintToken) { - while (!havePrintToken) { - int incomingMessage; - - print_incoming_data(); - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, - &incomingMessage, &Status); - if (incomingMessage) { - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, - MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - havePrintToken = 1; - nfound += nFoundbyWorker.nfound; - opts->not_cmp = opts->not_cmp | nFoundbyWorker.not_cmp; - /* send this task the work unit. */ - MPI_Send(&args, sizeof(args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, - MPI_COMM_WORLD); - } /* end if */ - } /* end while */ - } /* end if */ - /* if we do have the token, check for task to free up, or wait for a task to request - * it */ - else { - /* But first print all the data in our incoming queue */ - print_incoming_data(); - MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); - if (Status.MPI_TAG == MPI_TAG_DONE) { - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, - MPI_TAG_DONE, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker.nfound; - opts->not_cmp = opts->not_cmp | nFoundbyWorker.not_cmp; - MPI_Send(&args, sizeof(args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, - MPI_COMM_WORLD); - } /* end if */ - else if (Status.MPI_TAG == MPI_TAG_TOK_REQUEST) { - int incomingMessage; - - MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, - MPI_COMM_WORLD, &Status); - MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, - MPI_COMM_WORLD); - - do { - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, - &incomingMessage, &Status); - - print_incoming_data(); - } while (!incomingMessage); - - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, - MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker.nfound; - opts->not_cmp = opts->not_cmp | nFoundbyWorker.not_cmp; - MPI_Send(&args, sizeof(args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, - MPI_COMM_WORLD); - } /* end else-if */ - else { - fprintf(stderr, "ERROR: Invalid tag (%d) received \n", Status.MPI_TAG); - MPI_Abort(MPI_COMM_WORLD, 0); - MPI_Finalize(); - } /* end else */ - } /* end else */ - } /* end if */ - } /* end else */ -#endif /* H5_HAVE_PARALLEL */ - if (obj1_fullpath) - free(obj1_fullpath); - if (obj2_fullpath) - free(obj2_fullpath); - } /* end if */ - } /* end for */ - H5TOOLS_DEBUG("done with for loop - errstat:%d", opts->err_stat); + H5TOOLS_DEBUG("diff_match path1 - %s", obj1_fullpath); + H5TOOLS_DEBUG("diff_match path2 - %s", obj2_fullpath); + + /* get index to figure out type of the object in file1 */ + while (info1->paths[idx1].path && (strcmp(obj1_fullpath, info1->paths[idx1].path) != 0)) + idx1++; + /* get index to figure out type of the object in file2 */ + while (info2->paths[idx2].path && (strcmp(obj2_fullpath, info2->paths[idx2].path) != 0)) + idx2++; + + /* Set argdata to pass other args into diff() */ + argdata.type[0] = info1->paths[idx1].type; + argdata.type[1] = info2->paths[idx2].type; + argdata.is_same_trgobj = table->objs[i].is_same_trgobj; + + opts->cmn_objs = 1; + H5TOOLS_DEBUG("diff paths - errstat:%d", opts->err_stat); + + if (!g_Parallel) + nfound += diff(file1_id, obj1_fullpath, file2_id, obj2_fullpath, opts, &argdata); #ifdef H5_HAVE_PARALLEL - if (g_Parallel) { - /* make sure all tasks are done */ - while (busyTasks > 0) { - MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); - if (Status.MPI_TAG == MPI_TAG_DONE) { - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, - MPI_TAG_DONE, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker.nfound; - opts->not_cmp = opts->not_cmp | nFoundbyWorker.not_cmp; - busyTasks--; - } /* end if */ - else if (Status.MPI_TAG == MPI_TAG_TOK_REQUEST) { - MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, - &Status); - if (havePrintToken) { - int incomingMessage; - - MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); - - do { - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, - &Status); - - print_incoming_data(); - } while (!incomingMessage); - - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, - MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker.nfound; - opts->not_cmp = opts->not_cmp | nFoundbyWorker.not_cmp; - busyTasks--; - } /* end if */ - /* someone else must have it...wait for them to return it, then give it to the task that - * just asked for it. */ - else { - int source = Status.MPI_SOURCE; - int incomingMessage; - - do { - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, - &Status); - - print_incoming_data(); - } while (!incomingMessage); - - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, MPI_ANY_SOURCE, - MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker.nfound; - opts->not_cmp = opts->not_cmp | nFoundbyWorker.not_cmp; - busyTasks--; - MPI_Send(NULL, 0, MPI_BYTE, source, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); - } /* end else */ - } /* end else-if */ - else if (Status.MPI_TAG == MPI_TAG_TOK_RETURN) { - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, - MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker.nfound; - opts->not_cmp = opts->not_cmp | nFoundbyWorker.not_cmp; - busyTasks--; - havePrintToken = 1; - } /* end else-if */ - else if (Status.MPI_TAG == MPI_TAG_PRINT_DATA) { - char data[PRINT_DATA_MAX_SIZE + 1]; - memset(data, 0, PRINT_DATA_MAX_SIZE + 1); - - MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, - MPI_COMM_WORLD, &Status); - - parallel_print("%s", data); - } /* end else-if */ - else { - fprintf(stderr, "ph5diff-manager: ERROR!! Invalid tag (%d) received \n", Status.MPI_TAG); - MPI_Abort(MPI_COMM_WORLD, 0); - } /* end else */ - } /* end while */ - - /* Print any final data waiting in our queue */ - print_incoming_data(); - } /* end if */ - H5TOOLS_DEBUG("done with if block"); + else { + struct diff_mpi_args args; + + /* Dispatch diff requests to as many worker tasks as possible before + * handling incoming requests from worker tasks. + */ - free(workerTasks); + /* Check length of object names before handling and dispatching work */ + if (strlen(obj1_fullpath) > 255 || strlen(obj2_fullpath) > 255) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, + "parallel h5diff only supports object names up to 255 characters"); + + /* If no worker tasks are available, handle requests until one is */ + if (busyTasks == g_nTasks - 1) + if (H5DIFF_ERR == handle_worker_request(workerTasks, &busyTasks, opts, &nfound)) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't handle parallel worker task request"); + + /* Set up args to pass to worker task. */ + strcpy(args.name1, obj1_fullpath); + strcpy(args.name2, obj2_fullpath); + args.opts = *opts; + args.argdata = argdata; + + /* Dispatch diff request for this object to a worker task */ + if (H5DIFF_ERR == dispatch_diff_to_worker(&args, workerTasks, &busyTasks)) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't dispatch diff command to worker task"); + } +#endif + + if (obj1_fullpath) { + free(obj1_fullpath); + obj1_fullpath = NULL; + } + if (obj2_fullpath) { + free(obj2_fullpath); + obj2_fullpath = NULL; + } + } + H5TOOLS_DEBUG("done with for loop - errstat:%d", opts->err_stat); + +#ifdef H5_HAVE_PARALLEL + if (g_Parallel) { + /* Make sure all worker tasks are done */ + while (busyTasks > 0) { + if (H5DIFF_ERR == handle_worker_request(workerTasks, &busyTasks, opts, &nfound)) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't handle parallel worker task request"); + } } #endif /* H5_HAVE_PARALLEL */ +done: + free(obj1_fullpath); + free(obj2_fullpath); + +#ifdef H5_HAVE_PARALLEL + free(workerTasks); +#endif + opts->err_stat = opts->err_stat | ret_value; free_exclude_attr_list(opts); @@ -1932,3 +1700,148 @@ diff(hid_t file1_id, const char *path1, hid_t file2_id, const char *path2, diff_ return nfound; } + +#ifdef H5_HAVE_PARALLEL +/*------------------------------------------------------------------------- + * Function: handle_worker_request + * + * Purpose: Handles MPI communication from a worker task. Returns when a + * worker task becomes free (either a MPI_TAG_DONE message is + * received from it or a MPI_TAG_TOK_RETURN message is received + * from it after processing a MPI_TAG_TOK_REQUEST message event). + * + * Return: H5DIFF_NO_ERR on success/H5DIFF_ERR on failure + *------------------------------------------------------------------------- + */ +static diff_err_t +handle_worker_request(char *worker_tasks, int *n_busy_tasks, diff_opt_t *opts, hsize_t *n_diffs) +{ + struct diffs_found ndiffs_found; + MPI_Status status; + int task_idx = 0; + int source = 0; + herr_t ret_value = H5DIFF_NO_ERR; + + /* Must have at least one busy worker task */ + assert(*n_busy_tasks > 0); + + if (MPI_SUCCESS != (MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status))) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't check for message from worker task"); + source = status.MPI_SOURCE; + task_idx = source - 1; + + /* Currently, only MPI_TAG_DONE or MPI_TAG_TOK_REQUEST messages should be received + * from worker tasks. MPI_TAG_TOK_REQUEST messages begin a sequence that is handled + * "atomically" to simplify things and prevent the potential for interleaved output, + * out-of-order or unreceived messages, etc. + */ + if (status.MPI_TAG != MPI_TAG_DONE && status.MPI_TAG != MPI_TAG_TOK_REQUEST) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "invalid MPI message tag received from worker task"); + + if (status.MPI_TAG == MPI_TAG_DONE) { + if (MPI_SUCCESS != (MPI_Recv(&ndiffs_found, sizeof(ndiffs_found), MPI_BYTE, source, MPI_TAG_DONE, + MPI_COMM_WORLD, &status))) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't receive 'done' message from worker"); + + /* Update diff stats */ + opts->not_cmp = opts->not_cmp | ndiffs_found.not_cmp; + (*n_diffs) += ndiffs_found.nfound; + + /* Mark worker task as free */ + worker_tasks[task_idx] = 1; + (*n_busy_tasks)--; + } + else if (status.MPI_TAG == MPI_TAG_TOK_REQUEST) { + char data[PRINT_DATA_MAX_SIZE + 1]; + int incoming_output = 0; + + if (MPI_SUCCESS != + (MPI_Recv(NULL, 0, MPI_BYTE, source, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &status))) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't receive print token request message"); + + /* Give print token to worker task */ + if (MPI_SUCCESS != (MPI_Send(NULL, 0, MPI_BYTE, source, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD))) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't send print token to worker"); + + /* Print incoming output until print token is returned */ + incoming_output = 1; + do { + if (MPI_SUCCESS != (MPI_Probe(source, MPI_ANY_TAG, MPI_COMM_WORLD, &status))) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't check for message from worker task"); + + if (status.MPI_TAG == MPI_TAG_PRINT_DATA) { + memset(data, 0, PRINT_DATA_MAX_SIZE + 1); + if (MPI_SUCCESS != (MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, source, MPI_TAG_PRINT_DATA, + MPI_COMM_WORLD, &status))) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't receive output from worker task"); + + parallel_print("%s", data); + } + else if (status.MPI_TAG == MPI_TAG_TOK_RETURN) { + if (MPI_SUCCESS != (MPI_Recv(&ndiffs_found, sizeof(ndiffs_found), MPI_BYTE, source, + MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &status))) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't receive print token message from worker"); + + incoming_output = 0; + } + } while (incoming_output); + + /* Update diff stats */ + opts->not_cmp = opts->not_cmp | ndiffs_found.not_cmp; + (*n_diffs) += ndiffs_found.nfound; + + /* Mark worker task as free */ + worker_tasks[task_idx] = 1; + (*n_busy_tasks)--; + } + +done: + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: dispatch_diff_to_worker + * + * Purpose: Sends arguments to a worker task to allow it to start + * processing the differences between two objects. + * + * Return: H5DIFF_NO_ERR on success/H5DIFF_ERR on failure + *------------------------------------------------------------------------- + */ +static diff_err_t +dispatch_diff_to_worker(struct diff_mpi_args *args, char *worker_tasks, int *n_busy_tasks) +{ + int target_task = -1; + diff_err_t ret_value = H5DIFF_NO_ERR; + + /* Must have a free worker task */ + assert(*n_busy_tasks < g_nTasks - 1); + + /* Check array of tasks to see which ones are free. + * Manager task never does work, so workerTasks[0] is + * really worker task 0, or MPI rank 1. + */ + target_task = -1; + for (int n = 1; n < g_nTasks; n++) + if (worker_tasks[n - 1]) { + target_task = n - 1; + break; + } + + /* We should always find a free worker here */ + if (target_task < 0) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't find a free worker task to dispatch diff request to"); + + /* Send diff arguments to worker */ + if (MPI_SUCCESS != (MPI_Send(args, sizeof(struct diff_mpi_args), MPI_BYTE, target_task + 1, MPI_TAG_ARGS, + MPI_COMM_WORLD))) + H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "couldn't send diff arguments to worker task"); + + /* Mark worker task as busy */ + worker_tasks[target_task] = 0; + (*n_busy_tasks)++; + +done: + return ret_value; +} +#endif diff --git a/tools/src/h5diff/ph5diff_main.c b/tools/src/h5diff/ph5diff_main.c index 98e0c1da1b7..07fdb58bc09 100644 --- a/tools/src/h5diff/ph5diff_main.c +++ b/tools/src/h5diff/ph5diff_main.c @@ -48,6 +48,11 @@ main(int argc, char *argv[]) const char *objname2 = NULL; diff_opt_t opts; + MPI_Init(&argc, (char ***)&argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &nID); + MPI_Comm_size(MPI_COMM_WORLD, &g_nTasks); + h5tools_setprogname(PROGRAMNAME); h5tools_setstatus(EXIT_SUCCESS); @@ -57,11 +62,6 @@ main(int argc, char *argv[]) outBuffOffset = 0; g_Parallel = 1; - MPI_Init(&argc, (char ***)&argv); - - MPI_Comm_rank(MPI_COMM_WORLD, &nID); - MPI_Comm_size(MPI_COMM_WORLD, &g_nTasks); - if (g_nTasks == 1) { fprintf(stderr, "Only 1 task available...doing serial diff\n"); @@ -155,6 +155,7 @@ ph5diff_worker(int nID) /* Make certain we've received the filenames and opened the files already */ if (file1_id < 0 || file2_id < 0) { printf("ph5diff_worker: ERROR: work received before/without filenames\n"); + MPI_Abort(MPI_COMM_WORLD, 0); break; } @@ -165,34 +166,44 @@ ph5diff_worker(int nID) diffs.nfound = diff(file1_id, args.name1, file2_id, args.name2, &(args.opts), &(args.argdata)); diffs.not_cmp = args.opts.not_cmp; - /* If print buffer has something in it, request print token.*/ - if (outBuffOffset > 0) { + if ((outBuffOffset == 0) && !overflow_file) + /* Nothing to print. Send diffs to manager */ + MPI_Send(&diffs, sizeof(diffs), MPI_BYTE, 0, MPI_TAG_DONE, MPI_COMM_WORLD); + else { + /* + * If print buffer or overflow file have something in + * them, request print token. + */ MPI_Send(NULL, 0, MPI_BYTE, 0, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD); /* Wait for print token. */ MPI_Recv(NULL, 0, MPI_BYTE, 0, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD, &Status); - /* When get token, send all of our output to the manager task and then return the token */ - for (i = 0; i < outBuffOffset; i += PRINT_DATA_MAX_SIZE) - MPI_Send(outBuff + i, PRINT_DATA_MAX_SIZE, MPI_CHAR, 0, MPI_TAG_PRINT_DATA, - MPI_COMM_WORLD); + if (outBuffOffset > 0) { + /* When get token, send all of our output to the manager task and then return the token */ + for (i = 0; i < outBuffOffset; i += PRINT_DATA_MAX_SIZE) + MPI_Send(outBuff + i, PRINT_DATA_MAX_SIZE, MPI_CHAR, 0, MPI_TAG_PRINT_DATA, + MPI_COMM_WORLD); + } - /* An overflow file exists, so we send it's output to the manager too and then delete it */ + /* An overflow file exists, so we send its output to + * the manager too and then delete it. + */ if (overflow_file) { - char out_data[PRINT_DATA_MAX_SIZE]; + char out_data[PRINT_DATA_MAX_SIZE + 1]; int tmp; - memset(out_data, 0, PRINT_DATA_MAX_SIZE); + memset(out_data, 0, PRINT_DATA_MAX_SIZE + 1); i = 0; rewind(overflow_file); - while ((tmp = getc(overflow_file)) >= 0) { + while ((tmp = getc(overflow_file)) != EOF) { *(out_data + i++) = (char)tmp; if (i == PRINT_DATA_MAX_SIZE) { MPI_Send(out_data, PRINT_DATA_MAX_SIZE, MPI_CHAR, 0, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD); i = 0; - memset(out_data, 0, PRINT_DATA_MAX_SIZE); + memset(out_data, 0, PRINT_DATA_MAX_SIZE + 1); } } @@ -210,8 +221,6 @@ ph5diff_worker(int nID) MPI_Send(&diffs, sizeof(diffs), MPI_BYTE, 0, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD); } - else - MPI_Send(&diffs, sizeof(diffs), MPI_BYTE, 0, MPI_TAG_DONE, MPI_COMM_WORLD); } /* Check for leaving */ else if (Status.MPI_TAG == MPI_TAG_END) { @@ -220,10 +229,14 @@ ph5diff_worker(int nID) } else { printf("ph5diff_worker: ERROR: invalid tag (%d) received\n", Status.MPI_TAG); + MPI_Abort(MPI_COMM_WORLD, 0); break; } } + H5Fclose(file1_id); + H5Fclose(file2_id); + return; } @@ -241,13 +254,14 @@ void print_manager_output(void) { /* If there was something we buffered, let's print it now */ - if ((outBuffOffset > 0) && g_Parallel) { - printf("%s", outBuff); + if (g_Parallel) { + if (outBuffOffset > 0) + printf("%s", outBuff); if (overflow_file) { int tmp; rewind(overflow_file); - while ((tmp = getc(overflow_file)) >= 0) + while ((tmp = getc(overflow_file)) != EOF) putchar(tmp); fclose(overflow_file); overflow_file = NULL; @@ -257,8 +271,8 @@ print_manager_output(void) memset(outBuff, 0, OUTBUFF_SIZE); outBuffOffset = 0; } - else if ((outBuffOffset > 0) && !g_Parallel) { - fprintf(stderr, "h5diff error: outBuffOffset>0, but we're not in parallel!\n"); + else if (outBuffOffset > 0) { + fprintf(stderr, "h5diff error: outBuffOffset > 0, but we're not in parallel!\n"); } } diff --git a/tools/test/h5copy/CMakeTests.cmake b/tools/test/h5copy/CMakeTests.cmake index 2d7f5f7b04d..0069eaf6aea 100644 --- a/tools/test/h5copy/CMakeTests.cmake +++ b/tools/test/h5copy/CMakeTests.cmake @@ -30,7 +30,6 @@ set (LIST_OTHER_TEST_FILES h5copy_misc1.out - h5copy_misc1.err tudfilter.h5.txt tudfilter.h5_ERR.txt h5copy_plugin_fail_ERR.out.h5.txt diff --git a/tools/test/h5copy/expected/h5copy_misc1.err b/tools/test/h5copy/expected/h5copy_misc1.err deleted file mode 100644 index 2c2c867290b..00000000000 --- a/tools/test/h5copy/expected/h5copy_misc1.err +++ /dev/null @@ -1 +0,0 @@ -h5copy error: group doesn't exist. Use -p to create parent groups. diff --git a/tools/test/h5copy/testh5copy.sh.in b/tools/test/h5copy/testh5copy.sh.in index 916e2bec3e9..84a746c23b4 100644 --- a/tools/test/h5copy/testh5copy.sh.in +++ b/tools/test/h5copy/testh5copy.sh.in @@ -59,7 +59,6 @@ $SRC_H5COPY_TESTFILES/h5copy_extlinks_trg.h5 # List of expect files that will be copied over to local test dir LIST_OTHER_TEST_FILES=" $SRC_H5COPY_OUTFILES/h5copy_misc1.out -$SRC_H5COPY_OUTFILES/h5copy_misc1.err $SRC_H5COPY_OUTFILES/h5copy_help1.ddl $SRC_H5COPY_OUTFILES/h5copy_help2.ddl " @@ -79,6 +78,7 @@ CP='cp' DIRNAME='dirname' LS='ls' AWK='awk' +GREP='grep' nerrors=0 verbose=yes @@ -188,8 +188,8 @@ VERIFY_OUTPUT() TOOLTEST() { - actualout="$TESTDIR/tooltest.actualout" - actualerr="$TESTDIR/tooltest.actualerr" + actual="$TESTDIR/tooltest.actual" + actual_err="$TESTDIR/tooltest.actual_err" runh5diff=yes if [ "$1" = -i ]; then inputfile=$2 @@ -219,13 +219,13 @@ TOOLTEST() echo " output for '$H5COPY $@'" echo "#############################" $RUNSERIAL $H5COPY_BIN $@ - ) > $actualout 2> $actualerr + ) > $actual 2> $actual_err RET=$? if [ $RET != 0 ]; then echo "*FAILED*" echo "failed result is:" - cat $actualout + cat $actual nerrors="`expr $nerrors + 1`" else echo " PASSED" @@ -236,7 +236,7 @@ TOOLTEST() # Clean up output file if test -z "$HDF5_NOCLEANUP"; then - rm -f $actualout $actualerr $outputfile + rm -f $actual $actual_err $outputfile fi fi } @@ -244,8 +244,8 @@ TOOLTEST() # TOOLTEST back-to-back TOOLTEST_PREFILL() { - actualout="$TESTDIR/tooltest.actualout" - actualerr="$TESTDIR/tooltest.actualerr" + actual="$TESTDIR/tooltest.actual" + actual_err="$TESTDIR/tooltest.actual_err" runh5diff=yes if [ "$1" = -i ]; then inputfile=$2 @@ -269,13 +269,13 @@ TOOLTEST_PREFILL() echo " output for '$H5COPY $@'" echo "#############################" $RUNSERIAL $H5COPY_BIN -i $inputfile -o $outputfile -v -s $grp_name -d $grp_name2 - ) > $actualout 2> $actualerr + ) > $actual 2> $actual_err RET=$? if [ $RET != 0 ]; then echo "*FAILED*" echo "failed result is:" - cat $actualout + cat $actual nerrors="`expr $nerrors + 1`" else TESTING $H5COPY $@ @@ -284,13 +284,13 @@ TOOLTEST_PREFILL() echo " output for '$H5COPY $@'" echo "#############################" $RUNSERIAL $H5COPY_BIN -i $inputfile -o $outputfile -v -s $obj_name -d $obj_name2 - ) > $actualout 2> $actualerr + ) > $actual 2> $actual_err RET=$? if [ $RET != 0 ]; then echo "*FAILED*" echo "failed result is:" - cat $actualout + cat $actual nerrors="`expr $nerrors + 1`" else echo " PASSED" @@ -301,7 +301,7 @@ TOOLTEST_PREFILL() # Clean up output file if test -z "$HDF5_NOCLEANUP"; then - rm -f $actualout $actualerr $outputfile + rm -f $actual $actual_err $outputfile fi fi fi @@ -310,8 +310,8 @@ TOOLTEST_PREFILL() # TOOLTEST back-to-back TOOLTEST_SAME() { - actualout="$TESTDIR/tooltest.actualout" - actualerr="$TESTDIR/tooltest.actualerr" + actual="$TESTDIR/tooltest.actual" + actual_err="$TESTDIR/tooltest.actual_err" runh5diff=yes if [ "$1" = -i ]; then inputfile=$2 @@ -334,13 +334,13 @@ TOOLTEST_SAME() echo " output for '$H5COPY $@'" echo "#############################" $RUNSERIAL $H5COPY_BIN -i $inputfile -o $outputfile -v -s $grp_name -d $grp_name - ) > $actualout 2> $actualerr + ) > $actual 2> $actual_err RET=$? if [ $RET != 0 ]; then echo "*FAILED*" echo "failed result is:" - cat $actualout + cat $actual nerrors="`expr $nerrors + 1`" else TESTING $H5COPY $@ @@ -349,13 +349,13 @@ TOOLTEST_SAME() echo " output for '$H5COPY $@'" echo "#############################" $RUNSERIAL $H5COPY_BIN -i $outputfile -o $outputfile -v -s $grp_name -d $grp_name2 - ) > $actualout 2> $actualerr + ) > $actual 2> $actual_err RET=$? if [ $RET != 0 ]; then echo "*FAILED*" echo "failed result is:" - cat $actualout + cat $actual nerrors="`expr $nerrors + 1`" else echo " PASSED" @@ -366,50 +366,25 @@ TOOLTEST_SAME() # Clean up output file if test -z "$HDF5_NOCLEANUP"; then - rm -f $actualout $actualerr $outputfile + rm -f $actual $actual_err $outputfile fi fi fi } -# Compare the two text files -# PASS if same -# FAIL if different, and show the diff -# -# Assumed arguments: -# $1 is text file1 (expected output) -# $2 is text file2 (actual output) -CMP_OUTPUT() -{ - expect=$1 - actual=$2 - - VERIFY_OUTPUT $@ - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - echo " Expected result (*.ddl) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expect $actual; then - echo " PASSED" - else - echo "*FAILED*" - echo " Expected output differs from actual output" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' - fi -} - -TOOLTEST_FAIL() +# Call the h5copy tool and grep for a value +# txttype ERRTXT greps test error output, otherwise greps test output +GREPTEST() { - expectout="$TESTDIR/$1" - expecterr="$TESTDIR/`basename $1 .out`.err" - actualout="$TESTDIR/$1.actualout" - actualerr="$TESTDIR/$1.actualerr" - actualout_sav=${actualout}-sav - actualerr_sav=${actualerr}-sav + txttype=$1 + expectdata=$2 + expectout="$TESTDIR/$3" + expecterr="$TESTDIR/`basename $3 .out`.err" + actual="$TESTDIR/$3.actual" + actual_err="$TESTDIR/$3.actual_err" + shift + shift shift if [ "$1" = -i ]; then inputfile=$2 @@ -419,41 +394,32 @@ TOOLTEST_FAIL() outputfile=$4 fi + # Run test. TESTING $H5COPY $@ ( - #echo "#############################" - #echo " output for '$H5COPY $@'" - #echo "#############################" $RUNSERIAL $H5COPY_BIN $@ - ) > $actualout 2> $actualerr + ) > $actual 2> $actual_err RET=$? - # save actualout and actualerr in case they are needed later. - cp $actualout $actualout_sav - STDOUT_FILTER $actualout - cp $actualerr $actualerr_sav - STDERR_FILTER $actualerr - if [ $RET != 0 ]; then + if [ "$txttype" = "ERRTXT" ]; then + $GREP "$expectdata" $actual_err > /dev/null + else + $GREP "$expectdata" $actual > /dev/null + fi + + if [ $? -eq 0 ]; then echo " PASSED" - # Verifying output text from h5copy - if [ "$expectout" != "SKIP" ]; then - CMP_OUTPUT $expecterr $actualerr - fi else - echo "*FAILED*" - echo "failed result is:" - cat $actualout + echo " FAILED" nerrors="`expr $nerrors + 1`" fi - # Clean up output file if test -z "$HDF5_NOCLEANUP"; then - rm -f $actualout $actualerr $actualout_sav $actualerr_sav $outputfile + rm -f $actual $actual_err fi } - # Call the h5diff tool # H5DIFFTEST() @@ -469,22 +435,6 @@ H5DIFFTEST() fi } -# Call the h5diff tool with a call that is expected to fail -# -H5DIFFTEST_FAIL() -{ - VERIFY $@ - $RUNSERIAL $H5DIFF_BIN -q "$@" - RET=$? - - if [ $h5haveexitcode = 'yes' -a $RET != 1 ] ; then - echo "*FAILED*" - nerrors="`expr $nerrors + 1`" - else - echo " PASSED" - fi -} - # ADD_HELP_TEST TOOLTEST_HELP() { @@ -630,7 +580,7 @@ TEST_MISC() TESTFILE="$TESTDIR/h5copytst.h5" echo "Test copying object into group which doesn't exist, without -p" - TOOLTEST_FAIL h5copy_misc1.out -i $TESTFILE -o $TESTDIR/h5copy_misc1.out.h5 -v -s /simple -d /g1/g2/simple + GREPTEST ERRTXT "h5copy error" h5copy_misc1.out -i $TESTFILE -o $TESTDIR/h5copy_misc1.out.h5 -v -s /simple -d /g1/g2/simple echo "Test copying objects to the same file " TOOLTEST_SAME -i $TESTFILE -o $TESTDIR/samefile1.out.h5 /simple /simple_cp diff --git a/tools/test/h5diff/CMakeTests.cmake b/tools/test/h5diff/CMakeTests.cmake index 3d867c7ddee..3324aa3be53 100644 --- a/tools/test/h5diff/CMakeTests.cmake +++ b/tools/test/h5diff/CMakeTests.cmake @@ -192,7 +192,6 @@ h5diff_452.txt h5diff_453.txt h5diff_454.txt - dangling_link.err h5diff_455.txt h5diff_456.txt h5diff_457.txt @@ -254,7 +253,6 @@ h5diff_63.txt h5diff_600.txt h5diff_601.txt - h5diff_601_ERR.err h5diff_603.txt h5diff_604.txt h5diff_605.txt @@ -313,7 +311,6 @@ h5diff_8639.txt h5diff_reg.txt h5diff_ud.txt - h5diff_udfail.err h5diff_udfail.txt h5diff_v1.txt h5diff_v2.txt @@ -477,6 +474,82 @@ endif () endmacro () + macro (ADD_H5_CMP_TEST resultfile resultcode result_errcheck) + if (HDF5_TEST_SERIAL) + ADD_SH5_CMP_TEST (${resultfile} ${resultcode} ${result_errcheck} ${ARGN}) + endif () + if (H5_HAVE_PARALLEL AND HDF5_TEST_PARALLEL) + ADD_PH5_CMP_TEST (${resultfile} ${resultcode} ${result_errcheck} ${ARGN}) + endif () + endmacro () + + macro (ADD_SH5_CMP_TEST resultfile resultcode result_errcheck) + # If using memchecker add tests without using scripts + if (HDF5_USING_ANALYSIS_TOOL) + add_test (NAME H5DIFF-${resultfile} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ ${ARGN}) + if (${resultcode}) + set_tests_properties (H5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") + endif () + else () + add_test ( + NAME H5DIFF-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS:STRING=${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" + -D "TEST_OUTPUT=${resultfile}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}.txt" + -D "TEST_ERRREF=${result_errcheck}" + -D "TEST_APPEND=EXIT CODE:" + -P "${HDF_RESOURCES_DIR}/grepTest.cmake" + ) + endif () + set_tests_properties (H5DIFF-${resultfile} PROPERTIES + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles" + ) + if ("H5DIFF-${resultfile}" MATCHES "${HDF5_DISABLE_TESTS_REGEX}") + set_tests_properties (H5DIFF-${resultfile} PROPERTIES DISABLED true) + endif () + endmacro () + + macro (ADD_PH5_CMP_TEST resultfile resultcode result_errcheck) + # If using memchecker add tests without using scripts + if (HDF5_USING_ANALYSIS_TOOL) + add_test (NAME MPI_TEST_H5DIFF-${resultfile} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS} ${ARGN}) + set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/PAR/testfiles") + if (${resultcode}) + set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") + endif () + else () + add_test ( + NAME MPI_TEST_H5DIFF-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE}" + -D "TEST_ARGS:STRING=${MPIEXEC_NUMPROC_FLAG};${MPIEXEC_MAX_NUMPROCS};${MPIEXEC_PREFLAGS};$;${MPIEXEC_POSTFLAGS};${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/PAR/testfiles" + -D "TEST_OUTPUT=${resultfile}.out" + #-D "TEST_EXPECT=${resultcode}" + -D "TEST_EXPECT=0" # ph5diff currently always exits with a zero status code due to + # output from some MPI implementations from a non-zero exit code + -D "TEST_REFERENCE=${resultfile}.txt" + -D "TEST_ERRREF=${result_errcheck}" + -D "TEST_APPEND=EXIT CODE:" + -D "TEST_REF_APPEND=EXIT CODE: [0-9]" + -D "TEST_REF_FILTER=EXIT CODE: 0" + -D "TEST_SORT_COMPARE=TRUE" + -P "${HDF_RESOURCES_DIR}/grepTest.cmake" + ) + endif () + set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/PAR/testfiles" + ) + if ("MPI_TEST_H5DIFF-${resultfile}" MATCHES "${HDF5_DISABLE_TESTS_REGEX}") + set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES DISABLED true) + endif () + endmacro () + macro (ADD_H5_UD_TEST testname resultcode resultfile) if (NOT HDF5_USING_ANALYSIS_TOOL) if ("${resultcode}" STREQUAL "2") @@ -490,11 +563,12 @@ -D "TEST_OUTPUT=${resultfile}.out" -D "TEST_EXPECT=${resultcode}" -D "TEST_REFERENCE=${resultfile}.txt" + -D "TEST_ERRREF=user defined filter is not available" -D "TEST_APPEND=EXIT CODE:" -D "TEST_ENV_VAR=HDF5_PLUGIN_PATH" -D "TEST_ENV_VALUE=${CMAKE_BINARY_DIR}" -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_OUTPUT_DIRECTORY}" - -P "${HDF_RESOURCES_DIR}/runTest.cmake" + -P "${HDF_RESOURCES_DIR}/grepTest.cmake" ) else () add_test ( @@ -734,7 +808,7 @@ ADD_H5_TEST (h5diff_63 1 -v ${STRINGS1} ${STRINGS2} string4 string4) ADD_H5_TEST (h5diff_600 1 ${FILE1}) # 6.1: Check if non-exist object name is specified -ADD_H5_TEST (h5diff_601 2 ${FILE1} ${FILE1} nono_obj) +ADD_H5_CMP_TEST (h5diff_601 2 "Object could not be found" ${FILE1} ${FILE1} nono_obj) # ############################################################################## # # -d diff --git a/tools/test/h5diff/expected/dangling_link.err b/tools/test/h5diff/expected/dangling_link.err deleted file mode 100644 index 82802a1f23e..00000000000 --- a/tools/test/h5diff/expected/dangling_link.err +++ /dev/null @@ -1,4 +0,0 @@ -H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): - #000: (file name) line (number) in h5diff(): treat dangling link as error - major: Failure in tools library - minor: error in function diff --git a/tools/test/h5diff/expected/h5diff_601_ERR.err b/tools/test/h5diff/expected/h5diff_601_ERR.err deleted file mode 100644 index f9a7212dbd2..00000000000 --- a/tools/test/h5diff/expected/h5diff_601_ERR.err +++ /dev/null @@ -1,4 +0,0 @@ -H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): - #000: (file name) line (number) in h5diff(): Error: Object could not be found - major: Failure in tools library - minor: error in function diff --git a/tools/test/h5diff/expected/h5diff_udfail.err b/tools/test/h5diff/expected/h5diff_udfail.err deleted file mode 100644 index d51de38833a..00000000000 --- a/tools/test/h5diff/expected/h5diff_udfail.err +++ /dev/null @@ -1,12 +0,0 @@ - -file1 file2 ---------------------------------------- - x x / - x x /dynlibud - -group : and -0 differences found -dataset: and -0 differences found -Warning: dataset cannot be read, user defined filter is not available -EXIT CODE: 2 diff --git a/tools/test/h5diff/h5diff_plugin.sh.in b/tools/test/h5diff/h5diff_plugin.sh.in index f6783af8ff9..98ccf639d8c 100644 --- a/tools/test/h5diff/h5diff_plugin.sh.in +++ b/tools/test/h5diff/h5diff_plugin.sh.in @@ -63,7 +63,6 @@ LIST_HDF5_TEST_FILES=" $SRC_H5DIFF_TESTFILES/tudfilter.h5 $SRC_H5DIFF_TESTFILES/tudfilter2.h5 $SRC_H5DIFF_OUTFILES/h5diff_ud.txt -$SRC_H5DIFF_OUTFILES/h5diff_udfail.err $SRC_H5DIFF_OUTFILES/h5diff_udfail.txt " @@ -293,93 +292,6 @@ TOOLTEST() { rm -f $actual_sorted $expect_sorted fi } -# Same as TOOLSET except only err file checked -TOOLTEST_ERR() { - expect="$TESTDIR/$1" - expect_err="$TESTDIR/`basename $1 .txt`.err" - actual="$TESTDIR/`basename $1 .txt`.out" - actual_err="$TESTDIR/`basename $1 .txt`.out.err" - actual_sav=${actual}-sav - actual_err_sav=${actual_err}-sav - shift - if test -n "$pmode"; then - RUNCMD=$RUNPARALLEL - else - RUNCMD=$RUNSERIAL - fi - - # Run test. - TESTING $H5DIFF $@ - ( - #echo "#############################" - #echo "Expected output for '$H5DIFF $@'" - #echo "#############################" - cd $TESTDIR - eval $ENVCMD $RUNCMD $H5DIFF_BIN "$@" - ) >$actual 2>$actual_err - EXIT_CODE=$? - - # save actual and actual_err in case they are needed later. - cp $actual $actual_sav - STDOUT_FILTER $actual - cp $actual_err $actual_err_sav - STDERR_FILTER $actual_err - - # don't add exit code check in pmode, as it causes failure. (exit code - # is from mpirun not tool) - # if any problem occurs relate to an exit code, it will be caught in - # serial mode, so the test is fulfilled. - if test $h5haveexitcode = 'yes' -a -z "$pmode"; then - echo "EXIT CODE: $EXIT_CODE" >> $actual - fi - - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - echo " Expected result (*.ddl) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expect_err $actual_err; then - echo " PASSED" - elif test $h5haveexitcode = 'yes' -a -z "$pmode"; then - echo "*FAILED*" - echo " Expected result ($expect_err) differs from actual result ($actual_err)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect_err $actual_err |sed 's/^/ /' - else - # parallel mode output are often of different ordering from serial - # output. If the sorted expect_err and actual_err files compare the same, - # it is safe to assume the actual output match the expected file. - expect_sorted=expect_sorted - actual_sorted=actual_sorted - sort $expect_err -o $expect_sorted - sort $actual_err -o $actual_sorted - mv $expect_sorted.noexit $expect_sorted - - if $CMP $expect_sorted $actual_sorted; then - echo " PASSED" - else - echo "*FAILED*" - nerrors="`expr $nerrors + 1`" - if test yes = "$verbose"; then - echo "====Expected result ($expect_sorted) differs from actual result ($actual_sorted)" - $DIFF $expect_sorted $actual_sorted |sed 's/^/ /' - echo "====The actual output ($actual_sav)" - sed 's/^/ /' < $actual_sav - echo "====The actual stderr ($actual_err_sav)" - sed 's/^/ /' < $actual_err_sav - echo "====End of actual stderr ($actual_err_sav)" - echo "" - fi - fi - fi - - # Clean up output file - if test -z "$HDF5_NOCLEANUP"; then - rm -f $actual $actual_err $actual_sav $actual_err_sav - rm -f $actual_sorted $expect_sorted - fi -} ############################################################################## ### T H E T E S T S diff --git a/tools/test/h5diff/testh5diff.sh.in b/tools/test/h5diff/testh5diff.sh.in index 1378f07cf34..2cde4571982 100644 --- a/tools/test/h5diff/testh5diff.sh.in +++ b/tools/test/h5diff/testh5diff.sh.in @@ -234,7 +234,6 @@ $SRC_H5DIFF_OUTFILES/h5diff_451.txt $SRC_H5DIFF_OUTFILES/h5diff_452.txt $SRC_H5DIFF_OUTFILES/h5diff_453.txt $SRC_H5DIFF_OUTFILES/h5diff_454.txt -$SRC_H5DIFF_OUTFILES/dangling_link.err $SRC_H5DIFF_OUTFILES/h5diff_455.txt $SRC_H5DIFF_OUTFILES/h5diff_456.txt $SRC_H5DIFF_OUTFILES/h5diff_457.txt @@ -296,7 +295,6 @@ $SRC_H5DIFF_OUTFILES/h5diff_62.txt $SRC_H5DIFF_OUTFILES/h5diff_63.txt $SRC_H5DIFF_OUTFILES/h5diff_600.txt $SRC_H5DIFF_OUTFILES/h5diff_601.txt -$SRC_H5DIFF_OUTFILES/h5diff_601_ERR.err $SRC_H5DIFF_OUTFILES/h5diff_603.txt $SRC_H5DIFF_OUTFILES/h5diff_604.txt $SRC_H5DIFF_OUTFILES/h5diff_605.txt @@ -364,7 +362,7 @@ $SRC_H5DIFF_OUTFILES/h5diff_eps.txt # # copy test files and expected output files from source dirs to test dir # -COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_HDF5_VDS_TEST_FILES $LIST_HDF5_STD_REF_OBJ_TEST_FILES $LIST_OTHER_TEST_FILES $LIST_HDF5_TEST_FILES_XML $LIST_OTHER_TEST_FILES_XML" +COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_HDF5_VDS_TEST_FILES $LIST_HDF5_STD_REF_OBJ_TEST_FILES $LIST_OTHER_TEST_FILES" COPY_TESTFILES_TO_TESTDIR() { @@ -481,7 +479,6 @@ TESTING() { # TOOLTEST() { expect="$TESTDIR/$1" - expect_err="$TESTDIR/`basename $1 .txt`.err" actual="$TESTDIR/`basename $1 .txt`.out" actual_err="$TESTDIR/`basename $1 .txt`.out.err" actual_sav=${actual}-sav diff --git a/tools/test/h5dump/CMakeTests.cmake b/tools/test/h5dump/CMakeTests.cmake index 2369f63c746..546cfcbf011 100644 --- a/tools/test/h5dump/CMakeTests.cmake +++ b/tools/test/h5dump/CMakeTests.cmake @@ -25,6 +25,7 @@ file_space.ddl filter_fail.ddl non_existing.ddl + infinite_loop.ddl packedbits.ddl tall-1.ddl tall-2.ddl @@ -298,6 +299,7 @@ tfpformat.h5 tfvalues.h5 tgroup.h5 + 3790_infinite_loop.h5 tgrp_comments.h5 tgrpnullspace.h5 thlink.h5 @@ -368,32 +370,6 @@ tst_onion_dset_1d.h5 tst_onion_dset_1d.h5.onion ) - set (HDF5_ERROR_REFERENCE_TEST_FILES - filter_fail.err - non_existing.err - tall-1.err - tall-2A.err - tall-2A0.err - tall-2B.err - tarray1_big.err - tattrregR.err - tattr-3.err - tcomp-3.err - tdataregR.err - tdset-2.err - texceedsubblock.err - texceedsubcount.err - texceedsubstart.err - texceedsubstride.err - textlink.err - textlinkfar.err - textlinksrc.err - torderlinks1.err - torderlinks2.err - tgroup-2.err - tperror.err - tslink-D.err - ) # make test dir file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") @@ -417,10 +393,6 @@ HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/expected/${tst_h5N_file}" "${PROJECT_BINARY_DIR}/testfiles/std/${tst_h5N_file}-N" "h5dump_std_files") endforeach () - foreach (tst_error_file ${HDF5_ERROR_REFERENCE_TEST_FILES}) - HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/errfiles/${tst_error_file}" "${PROJECT_BINARY_DIR}/testfiles/std/${tst_error_file}" "h5dump_std_files") - endforeach () - # -------------------------------------------------------------------- # Special file handling # -------------------------------------------------------------------- @@ -1266,10 +1238,10 @@ ADD_H5_TEST (tindicessub4 0 --enable-error-stack -d 4d -s 0,0,1,2 -c 2,2,3,2 -S 1,1,3,3 -k 1,1,2,2 taindices.h5) # Exceed the dimensions for subsetting - ADD_H5_TEST (texceedsubstart 1 --enable-error-stack -d 1d -s 1,3 taindices.h5) - ADD_H5_TEST (texceedsubcount 1 --enable-error-stack -d 1d -c 1,3 taindices.h5) - ADD_H5_TEST (texceedsubstride 1 --enable-error-stack -d 1d -S 1,3 taindices.h5) - ADD_H5_TEST (texceedsubblock 1 --enable-error-stack -d 1d -k 1,3 taindices.h5) + ADD_H5ERR_MASK_TEST (texceedsubstart 1 "exceed dataset dims" --enable-error-stack -d 1d -s 1,3 taindices.h5) + ADD_H5ERR_MASK_TEST (texceedsubcount 1 "exceed dataset dims" --enable-error-stack -d 1d -c 1,3 taindices.h5) + ADD_H5ERR_MASK_TEST (texceedsubstride 1 "exceed dataset dims" --enable-error-stack -d 1d -S 1,3 taindices.h5) + ADD_H5ERR_MASK_TEST (texceedsubblock 1 "exceed dataset dims" --enable-error-stack -d 1d -k 1,3 taindices.h5) # tests for filters # SZIP @@ -1421,21 +1393,24 @@ ADD_H5_TEST_EXPORT (tall-6 tall.h5 0 --enable-error-stack -d /g1/g1.1/dset1.1.1 -y -o) # test for non-existing file - ADD_H5_TEST (non_existing 1 --enable-error-stack tgroup.h5 non_existing.h5) + ADD_H5ERR_MASK_TEST (non_existing 1 "unable to open file" --enable-error-stack tgroup.h5 non_existing.h5) + + # test to verify github issue#3790: infinite loop closing library + ADD_H5ERR_MASK_TEST (infinite_loop 1 "unable to open file" 3790_infinite_loop.h5) # test to verify HDFFV-10333: error similar to H5O_attr_decode in the jira issue - ADD_H5_TEST (err_attr_dspace 1 err_attr_dspace.h5) + ADD_H5ERR_MASK_TEST (err_attr_dspace 1 "error getting attribute information" err_attr_dspace.h5) # test to verify HDFFV-9407: long double full precision # ADD_H5_GREP_TEST (t128bit_float 1 "1.123456789012345" -m %.35Lg t128bit_float.h5) # test to verify HDFFV-10480: out of bounds read in H5O_fill_new[old]_decode - ADD_H5_TEST (tCVE_2018_11206_fill_old 1 tCVE_2018_11206_fill_old.h5) - ADD_H5_TEST (tCVE_2018_11206_fill_new 1 tCVE_2018_11206_fill_new.h5) + ADD_H5ERR_MASK_TEST (tCVE_2018_11206_fill_old 1 "" tCVE_2018_11206_fill_old.h5) + ADD_H5ERR_MASK_TEST (tCVE_2018_11206_fill_new 1 "" tCVE_2018_11206_fill_new.h5) # test to verify fix for CVE-2021-37501: multiplication overflow in H5O__attr_decode() # https://github.com/ST4RF4LL/Something_Found/blob/main/HDF5_v1.13.0_h5dump_heap_overflow.assets/poc - ADD_H5_TEST (tCVE-2021-37501_attr_decode 1 tCVE-2021-37501_attr_decode.h5) + ADD_H5ERR_MASK_TEST (tCVE-2021-37501_attr_decode 1 "error getting attribute information" tCVE-2021-37501_attr_decode.h5) # onion VFD tests ADD_H5_TEST (tst_onion_objs 0 --enable-error-stack --vfd-name onion --vfd-info 3 tst_onion_objs.h5) diff --git a/tools/test/h5dump/CMakeTestsPBITS.cmake b/tools/test/h5dump/CMakeTestsPBITS.cmake index 4ae68846a5e..9e72ae10f1f 100644 --- a/tools/test/h5dump/CMakeTestsPBITS.cmake +++ b/tools/test/h5dump/CMakeTestsPBITS.cmake @@ -80,21 +80,6 @@ tarray1.h5 tcompound.h5 ) - set (HDF5_ERROR_REFERENCE_PBITS - tnofilename-with-packed-bits.err - tpbitsCharLengthExceeded.err - tpbitsCharOffsetExceeded.err - tpbitsIncomplete.err - tpbitsIntLengthExceeded.err - tpbitsIntOffsetExceeded.err - tpbitsLengthExceeded.err - tpbitsLengthPositive.err - tpbitsLongLengthExceeded.err - tpbitsLongOffsetExceeded.err - tpbitsMaxExceeded.err - tpbitsOffsetExceeded.err - tpbitsOffsetNegative.err - ) foreach (pbits_h5_file ${HDF5_REFERENCE_TEST_PBITS}) HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/testfiles/${pbits_h5_file}" "${PROJECT_BINARY_DIR}/testfiles/pbits/${pbits_h5_file}" "h5dump_pbits_files") @@ -103,10 +88,6 @@ foreach (ddl_pbits ${HDF5_REFERENCE_PBITS}) HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/expected/pbits/${ddl_pbits}" "${PROJECT_BINARY_DIR}/testfiles/pbits/${ddl_pbits}" "h5dump_pbits_files") endforeach () - - foreach (ddl_err_pbits ${HDF5_ERROR_REFERENCE_PBITS}) - HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/errfiles/pbits/${ddl_err_pbits}" "${PROJECT_BINARY_DIR}/testfiles/pbits/${ddl_err_pbits}" "h5dump_pbits_files") - endforeach () add_custom_target(h5dump_pbits_files ALL COMMENT "Copying files needed by h5dump_pbits tests" DEPENDS ${h5dump_pbits_files_list}) ############################################################################## @@ -115,7 +96,7 @@ ############################################################################## ############################################################################## - macro (ADD_H5_PBITS_TEST resultfile resultcode) + macro (ADD_H5_PBITS_TEST resultfile resultcode result_errcheck) # If using memchecker add tests without using scripts if (HDF5_USING_ANALYSIS_TOOL) add_test (NAME H5DUMP-${resultfile} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ ${ARGN}) @@ -123,18 +104,34 @@ set_tests_properties (H5DUMP-${resultfile} PROPERTIES WILL_FAIL "true") endif () else () - add_test ( - NAME H5DUMP-${resultfile} - COMMAND "${CMAKE_COMMAND}" - -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" - -D "TEST_PROGRAM=$" - -D "TEST_ARGS:STRING=${ARGN}" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles/pbits" - -D "TEST_OUTPUT=${resultfile}.out" - -D "TEST_EXPECT=${resultcode}" - -D "TEST_REFERENCE=${resultfile}.ddl" - -P "${HDF_RESOURCES_DIR}/runTest.cmake" - ) + if (${resultcode}) + add_test ( + NAME H5DUMP-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS:STRING=${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles/pbits" + -D "TEST_OUTPUT=${resultfile}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}.ddl" + -D "TEST_ERRREF=${result_errcheck}" + -P "${HDF_RESOURCES_DIR}/grepTest.cmake" + ) + else () + add_test ( + NAME H5DUMP-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS:STRING=${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles/pbits" + -D "TEST_OUTPUT=${resultfile}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}.ddl" + -P "${HDF_RESOURCES_DIR}/runTest.cmake" + ) + endif () endif () set_tests_properties (H5DUMP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/pbits" @@ -152,7 +149,7 @@ # test failure handling # Missing file name - ADD_H5_PBITS_TEST (tnofilename-with-packed-bits 1 --enable-error-stack) + ADD_H5_PBITS_TEST (tnofilename-with-packed-bits 1 "missing file name" --enable-error-stack) # Limits: # Maximum number of packed bits is 8 (for now). # Maximum integer size is 8*sizeof(long long). @@ -162,69 +159,69 @@ # Normal operation on both signed and unsigned int datasets. # Sanity check # Their rawdata output should be the same. - ADD_H5_PBITS_TEST (tpbitsSignedWhole 0 --enable-error-stack -d /DS08BITS -M 0,8 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedWhole 0 --enable-error-stack -d /DU08BITS -M 0,8 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedIntWhole 0 --enable-error-stack -d /DS16BITS -M 0,16 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedIntWhole 0 --enable-error-stack -d /DU16BITS -M 0,16 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLongWhole 0 --enable-error-stack -d /DS32BITS -M 0,32 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLongWhole 0 --enable-error-stack -d /DU32BITS -M 0,32 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLongLongWhole 0 --enable-error-stack -d /DS64BITS -M 0,64 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLongLongWhole 0 --enable-error-stack -d /DU64BITS -M 0,64 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLongLongWhole63 0 --enable-error-stack -d /DS64BITS -M 0,63 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLongLongWhole63 0 --enable-error-stack -d /DU64BITS -M 0,63 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLongLongWhole1 0 --enable-error-stack -d /DS64BITS -M 1,63 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLongLongWhole1 0 --enable-error-stack -d /DU64BITS -M 1,63 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedWhole 0 "" --enable-error-stack -d /DS08BITS -M 0,8 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedWhole 0 "" --enable-error-stack -d /DU08BITS -M 0,8 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedIntWhole 0 "" --enable-error-stack -d /DS16BITS -M 0,16 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedIntWhole 0 "" --enable-error-stack -d /DU16BITS -M 0,16 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLongWhole 0 "" --enable-error-stack -d /DS32BITS -M 0,32 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLongWhole 0 "" --enable-error-stack -d /DU32BITS -M 0,32 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLongLongWhole 0 "" --enable-error-stack -d /DS64BITS -M 0,64 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLongLongWhole 0 "" --enable-error-stack -d /DU64BITS -M 0,64 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLongLongWhole63 0 "" --enable-error-stack -d /DS64BITS -M 0,63 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLongLongWhole63 0 "" --enable-error-stack -d /DU64BITS -M 0,63 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLongLongWhole1 0 "" --enable-error-stack -d /DS64BITS -M 1,63 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLongLongWhole1 0 "" --enable-error-stack -d /DU64BITS -M 1,63 packedbits.h5) # Half sections - ADD_H5_PBITS_TEST (tpbitsSigned4 0 --enable-error-stack -d /DS08BITS -M 0,4,4,4 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsigned4 0 --enable-error-stack -d /DU08BITS -M 0,4,4,4 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedInt8 0 --enable-error-stack -d /DS16BITS -M 0,8,8,8 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedInt8 0 --enable-error-stack -d /DU16BITS -M 0,8,8,8 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLong16 0 --enable-error-stack -d /DS32BITS -M 0,16,16,16 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLong16 0 --enable-error-stack -d /DU32BITS -M 0,16,16,16 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLongLong32 0 --enable-error-stack -d /DS64BITS -M 0,32,32,32 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLongLong32 0 --enable-error-stack -d /DU64BITS -M 0,32,32,32 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSigned4 0 "" --enable-error-stack -d /DS08BITS -M 0,4,4,4 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsigned4 0 "" --enable-error-stack -d /DU08BITS -M 0,4,4,4 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedInt8 0 "" --enable-error-stack -d /DS16BITS -M 0,8,8,8 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedInt8 0 "" --enable-error-stack -d /DU16BITS -M 0,8,8,8 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLong16 0 "" --enable-error-stack -d /DS32BITS -M 0,16,16,16 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLong16 0 "" --enable-error-stack -d /DU32BITS -M 0,16,16,16 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLongLong32 0 "" --enable-error-stack -d /DS64BITS -M 0,32,32,32 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLongLong32 0 "" --enable-error-stack -d /DU64BITS -M 0,32,32,32 packedbits.h5) # Quarter sections - ADD_H5_PBITS_TEST (tpbitsSigned2 0 --enable-error-stack -d /DS08BITS -M 0,2,2,2,4,2,6,2 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsigned2 0 --enable-error-stack -d /DU08BITS -M 0,2,2,2,4,2,6,2 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedInt4 0 --enable-error-stack -d /DS16BITS -M 0,4,4,4,8,4,12,4 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedInt4 0 --enable-error-stack -d /DU16BITS -M 0,4,4,4,8,4,12,4 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLong8 0 --enable-error-stack -d /DS32BITS -M 0,8,8,8,16,8,24,8 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLong8 0 --enable-error-stack -d /DU32BITS -M 0,8,8,8,16,8,24,8 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLongLong16 0 --enable-error-stack -d /DS64BITS -M 0,16,16,16,32,16,48,16 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLongLong16 0 --enable-error-stack -d /DU64BITS -M 0,16,16,16,32,16,48,16 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSigned2 0 "" --enable-error-stack -d /DS08BITS -M 0,2,2,2,4,2,6,2 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsigned2 0 "" --enable-error-stack -d /DU08BITS -M 0,2,2,2,4,2,6,2 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedInt4 0 "" --enable-error-stack -d /DS16BITS -M 0,4,4,4,8,4,12,4 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedInt4 0 "" --enable-error-stack -d /DU16BITS -M 0,4,4,4,8,4,12,4 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLong8 0 "" --enable-error-stack -d /DS32BITS -M 0,8,8,8,16,8,24,8 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLong8 0 "" --enable-error-stack -d /DU32BITS -M 0,8,8,8,16,8,24,8 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLongLong16 0 "" --enable-error-stack -d /DS64BITS -M 0,16,16,16,32,16,48,16 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLongLong16 0 "" --enable-error-stack -d /DU64BITS -M 0,16,16,16,32,16,48,16 packedbits.h5) # Begin and End - ADD_H5_PBITS_TEST (tpbitsSigned 0 --enable-error-stack -d /DS08BITS -M 0,2,2,6 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsigned 0 --enable-error-stack -d /DU08BITS -M 0,2,2,6 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedInt 0 --enable-error-stack -d /DS16BITS -M 0,2,10,6 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedInt 0 --enable-error-stack -d /DU16BITS -M 0,2,10,6 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLong 0 --enable-error-stack -d /DS32BITS -M 0,2,26,6 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLong 0 --enable-error-stack -d /DU32BITS -M 0,2,26,6 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsSignedLongLong 0 --enable-error-stack -d /DS64BITS -M 0,2,58,6 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsUnsignedLongLong 0 --enable-error-stack -d /DU64BITS -M 0,2,58,6 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSigned 0 "" --enable-error-stack -d /DS08BITS -M 0,2,2,6 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsigned 0 "" --enable-error-stack -d /DU08BITS -M 0,2,2,6 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedInt 0 "" --enable-error-stack -d /DS16BITS -M 0,2,10,6 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedInt 0 "" --enable-error-stack -d /DU16BITS -M 0,2,10,6 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLong 0 "" --enable-error-stack -d /DS32BITS -M 0,2,26,6 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLong 0 "" --enable-error-stack -d /DU32BITS -M 0,2,26,6 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsSignedLongLong 0 "" --enable-error-stack -d /DS64BITS -M 0,2,58,6 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsUnsignedLongLong 0 "" --enable-error-stack -d /DU64BITS -M 0,2,58,6 packedbits.h5) # Overlapped packed bits. - ADD_H5_PBITS_TEST (tpbitsOverlapped 0 --enable-error-stack -d /DS08BITS -M 0,1,1,1,2,1,0,3 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsOverlapped 0 "" --enable-error-stack -d /DS08BITS -M 0,1,1,1,2,1,0,3 packedbits.h5) # Maximum number of packed bits. - ADD_H5_PBITS_TEST (tpbitsMax 0 --enable-error-stack -d /DS08BITS -M 0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsMax 0 "" --enable-error-stack -d /DS08BITS -M 0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1 packedbits.h5) # Compound type. - ADD_H5_PBITS_TEST (tpbitsCompound 0 --enable-error-stack -d /dset1 -M 0,1,1,1 tcompound.h5) + ADD_H5_PBITS_TEST (tpbitsCompound 0 "" --enable-error-stack -d /dset1 -M 0,1,1,1 tcompound.h5) # Array type. - ADD_H5_PBITS_TEST (tpbitsArray 0 --enable-error-stack -d /Dataset1 -M 0,1,1,1 tarray1.h5) + ADD_H5_PBITS_TEST (tpbitsArray 0 "" --enable-error-stack -d /Dataset1 -M 0,1,1,1 tarray1.h5) # Test Error handling. # Too many packed bits requested. Max is 8 for now. - ADD_H5_PBITS_TEST (tpbitsMaxExceeded 1 --enable-error-stack -d /DS08BITS -M 0,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsMaxExceeded 1 "Too many masks requested" --enable-error-stack -d /DS08BITS -M 0,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1 packedbits.h5) # Offset too large. Max is 8*sizeof(long long. - ADD_H5_PBITS_TEST (tpbitsOffsetExceeded 1 --enable-error-stack -d /DS08BITS -M 64,1 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsCharOffsetExceeded 0 --enable-error-stack -d /DS08BITS -M 8,1 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsIntOffsetExceeded 0 --enable-error-stack -d /DS16BITS -M 16,1 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsLongOffsetExceeded 0 --enable-error-stack -d /DS32BITS -M 32,1 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsOffsetExceeded 1 "must be between 0 and 63" --enable-error-stack -d /DS08BITS -M 64,1 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsCharOffsetExceeded 0 "" --enable-error-stack -d /DS08BITS -M 8,1 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsIntOffsetExceeded 0 "" --enable-error-stack -d /DS16BITS -M 16,1 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsLongOffsetExceeded 0 "" --enable-error-stack -d /DS32BITS -M 32,1 packedbits.h5) # Bad offset, must not be negative. - ADD_H5_PBITS_TEST (tpbitsOffsetNegative 1 --enable-error-stack -d /DS08BITS -M -1,1 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsOffsetNegative 1 "Bad mask list" --enable-error-stack -d /DS08BITS -M -1,1 packedbits.h5) # Bad length, must not be positive. - ADD_H5_PBITS_TEST (tpbitsLengthPositive 1 --enable-error-stack -d /DS08BITS -M 4,0 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsLengthPositive 1 "must be positive" --enable-error-stack -d /DS08BITS -M 4,0 packedbits.h5) # Offset+Length is too large. Max is 8*sizeof(long long). - ADD_H5_PBITS_TEST (tpbitsLengthExceeded 1 --enable-error-stack -d /DS08BITS -M 37,28 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsCharLengthExceeded 0 --enable-error-stack -d /DS08BITS -M 2,7 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsIntLengthExceeded 0 --enable-error-stack -d /DS16BITS -M 10,7 packedbits.h5) - ADD_H5_PBITS_TEST (tpbitsLongLengthExceeded 0 --enable-error-stack -d /DS32BITS -M 26,7 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsLengthExceeded 1 "too large" --enable-error-stack -d /DS08BITS -M 37,28 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsCharLengthExceeded 0 "" --enable-error-stack -d /DS08BITS -M 2,7 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsIntLengthExceeded 0 "" --enable-error-stack -d /DS16BITS -M 10,7 packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsLongLengthExceeded 0 "" --enable-error-stack -d /DS32BITS -M 26,7 packedbits.h5) # Incomplete pair of packed bits request. - ADD_H5_PBITS_TEST (tpbitsIncomplete 1 --enable-error-stack -d /DS08BITS -M 0,2,2,1,0,2,2, packedbits.h5) + ADD_H5_PBITS_TEST (tpbitsIncomplete 1 "Bad mask list" --enable-error-stack -d /DS08BITS -M 0,2,2,1,0,2,2, packedbits.h5) diff --git a/tools/test/h5dump/CMakeTestsVDS.cmake b/tools/test/h5dump/CMakeTestsVDS.cmake index d1dc5411a28..12cf07b4a37 100644 --- a/tools/test/h5dump/CMakeTestsVDS.cmake +++ b/tools/test/h5dump/CMakeTestsVDS.cmake @@ -80,8 +80,6 @@ vds-percival-unlim-maxmin.h5 vds-eiger.h5 ) - set (HDF5_ERROR_REFERENCE_VDS - ) foreach (vds_h5_file ${HDF5_REFERENCE_TEST_VDS}) HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/testfiles/vds/${vds_h5_file}" "${PROJECT_BINARY_DIR}/testfiles/vds/${vds_h5_file}" "h5dump_vds_files") @@ -95,9 +93,6 @@ HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/expected/vds/${ddl_vds}" "${PROJECT_BINARY_DIR}/testfiles/vds/prefix/${ddl_vds}" "h5dump_vds_files") endforeach () - foreach (ddl_vds ${HDF5_ERROR_REFERENCE_VDS}) - HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/errfiles/${ddl_vds}" "${PROJECT_BINARY_DIR}/testfiles/vds/${ddl_vds}" "h5dump_vds_files") - endforeach () add_custom_target(h5dump_vds_files ALL COMMENT "Copying files needed by h5dump_vds tests" DEPENDS ${h5dump_vds_files_list}) ############################################################################## diff --git a/tools/test/h5dump/errfiles/filter_fail.err b/tools/test/h5dump/errfiles/filter_fail.err deleted file mode 100644 index 07b0aa02193..00000000000 --- a/tools/test/h5dump/errfiles/filter_fail.err +++ /dev/null @@ -1,33 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Dread(): can't read data - major: Dataset - minor: Read failed - #001: (file name) line (number) in H5VL_dataset_read(): dataset read failed - major: Virtual Object Layer - minor: Read failed - #002: (file name) line (number) in H5VL__dataset_read(): dataset read failed - major: Virtual Object Layer - minor: Read failed - #003: (file name) line (number) in H5VL__native_dataset_read(): can't read data - major: Dataset - minor: Read failed - #004: (file name) line (number) in H5D__read(): can't read data - major: Dataset - minor: Read failed - #005: (file name) line (number) in H5D__chunk_read(): unable to read raw data chunk - major: Low-level I/O - minor: Read failed - #006: (file name) line (number) in H5D__chunk_lock(): data pipeline read failed - major: Dataset - minor: Filter operation failed - #007: (file name) line (number) in H5Z_pipeline(): required filter 'filter_fail_test' is not registered - major: Data filters - minor: Read failed - #008: (file name) line (number) in H5PL_load(): filter plugins disabled - major: Plugin for dynamically loaded library - minor: Unable to load metadata into cache -h5dump error: unable to print data -H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): - #000: (file name) line (number) in h5tools_dump_simple_dset(): H5Dread failed - major: Failure in tools library - minor: error in function diff --git a/tools/test/h5dump/errfiles/non_existing.err b/tools/test/h5dump/errfiles/non_existing.err deleted file mode 100644 index f7e3afa4f68..00000000000 --- a/tools/test/h5dump/errfiles/non_existing.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: unable to open file "non_existing.h5" diff --git a/tools/test/h5dump/errfiles/pbits/tnofilename-with-packed-bits.err b/tools/test/h5dump/errfiles/pbits/tnofilename-with-packed-bits.err deleted file mode 100644 index 84a701100a6..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tnofilename-with-packed-bits.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: missing file name diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsCharLengthExceeded.err b/tools/test/h5dump/errfiles/pbits/tpbitsCharLengthExceeded.err deleted file mode 100644 index e5854ea23df..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsCharLengthExceeded.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Packed Bit offset+length value(9) too large. Max is 8 diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsCharOffsetExceeded.err b/tools/test/h5dump/errfiles/pbits/tpbitsCharOffsetExceeded.err deleted file mode 100644 index e5854ea23df..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsCharOffsetExceeded.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Packed Bit offset+length value(9) too large. Max is 8 diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsIncomplete.err b/tools/test/h5dump/errfiles/pbits/tpbitsIncomplete.err deleted file mode 100644 index e0abee535be..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsIncomplete.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Bad mask list(0,2,2,1,0,2,2,) diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsIntLengthExceeded.err b/tools/test/h5dump/errfiles/pbits/tpbitsIntLengthExceeded.err deleted file mode 100644 index 7dd88edce5d..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsIntLengthExceeded.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Packed Bit offset+length value(17) too large. Max is 16 diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsIntOffsetExceeded.err b/tools/test/h5dump/errfiles/pbits/tpbitsIntOffsetExceeded.err deleted file mode 100644 index 7dd88edce5d..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsIntOffsetExceeded.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Packed Bit offset+length value(17) too large. Max is 16 diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsLengthExceeded.err b/tools/test/h5dump/errfiles/pbits/tpbitsLengthExceeded.err deleted file mode 100644 index d4673f25dde..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsLengthExceeded.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Packed Bit offset+length value(65) too large. Max is 64 diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsLengthPositive.err b/tools/test/h5dump/errfiles/pbits/tpbitsLengthPositive.err deleted file mode 100644 index 49280074802..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsLengthPositive.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Packed Bit length value(0) must be positive. diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsLongLengthExceeded.err b/tools/test/h5dump/errfiles/pbits/tpbitsLongLengthExceeded.err deleted file mode 100644 index 0318f79c977..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsLongLengthExceeded.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Packed Bit offset+length value(33) too large. Max is 32 diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsLongOffsetExceeded.err b/tools/test/h5dump/errfiles/pbits/tpbitsLongOffsetExceeded.err deleted file mode 100644 index 0318f79c977..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsLongOffsetExceeded.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Packed Bit offset+length value(33) too large. Max is 32 diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsMaxExceeded.err b/tools/test/h5dump/errfiles/pbits/tpbitsMaxExceeded.err deleted file mode 100644 index a8d12fc180b..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsMaxExceeded.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Too many masks requested (max. 8). Mask list(0,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1) diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsOffsetExceeded.err b/tools/test/h5dump/errfiles/pbits/tpbitsOffsetExceeded.err deleted file mode 100644 index b7d6dad259d..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsOffsetExceeded.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Packed Bit offset value(64) must be between 0 and 63 diff --git a/tools/test/h5dump/errfiles/pbits/tpbitsOffsetNegative.err b/tools/test/h5dump/errfiles/pbits/tpbitsOffsetNegative.err deleted file mode 100644 index 8a027c18545..00000000000 --- a/tools/test/h5dump/errfiles/pbits/tpbitsOffsetNegative.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: Bad mask list(-1,1) diff --git a/tools/test/h5dump/errfiles/tall-1.err b/tools/test/h5dump/errfiles/tall-1.err deleted file mode 100644 index 84401596034..00000000000 --- a/tools/test/h5dump/errfiles/tall-1.err +++ /dev/null @@ -1,37 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open external file, external link file name = 'somefile' - major: Links - minor: Unable to open file diff --git a/tools/test/h5dump/errfiles/tall-2A.err b/tools/test/h5dump/errfiles/tall-2A.err deleted file mode 100644 index 84401596034..00000000000 --- a/tools/test/h5dump/errfiles/tall-2A.err +++ /dev/null @@ -1,37 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open external file, external link file name = 'somefile' - major: Links - minor: Unable to open file diff --git a/tools/test/h5dump/errfiles/tall-2A0.err b/tools/test/h5dump/errfiles/tall-2A0.err deleted file mode 100644 index 84401596034..00000000000 --- a/tools/test/h5dump/errfiles/tall-2A0.err +++ /dev/null @@ -1,37 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open external file, external link file name = 'somefile' - major: Links - minor: Unable to open file diff --git a/tools/test/h5dump/errfiles/tall-2B.err b/tools/test/h5dump/errfiles/tall-2B.err deleted file mode 100644 index 84401596034..00000000000 --- a/tools/test/h5dump/errfiles/tall-2B.err +++ /dev/null @@ -1,37 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open external file, external link file name = 'somefile' - major: Links - minor: Unable to open file diff --git a/tools/test/h5dump/errfiles/tarray1_big.err b/tools/test/h5dump/errfiles/tarray1_big.err deleted file mode 100644 index a20b0b7ae8d..00000000000 --- a/tools/test/h5dump/errfiles/tarray1_big.err +++ /dev/null @@ -1,31 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Rget_obj_type3(): unable to get object token - major: References - minor: Can't get value - #001: (file name) line (number) in H5R__get_obj_token(): NULL token size - major: References - minor: Unable to copy object -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Rget_obj_type3(): unable to get object token - major: References - minor: Can't get value - #001: (file name) line (number) in H5R__get_obj_token(): NULL token size - major: References - minor: Unable to copy object -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Rget_obj_type3(): unable to get object token - major: References - minor: Can't get value - #001: (file name) line (number) in H5R__get_obj_token(): NULL token size - major: References - minor: Unable to copy object -H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): - #000: (file name) line (number) in h5tools_dump_data(): H5Rget_obj_type3 H5R_OBJECT1 failed - major: Failure in tools library - minor: error in function - #001: (file name) line (number) in h5tools_dump_data(): H5Rget_obj_type3 H5R_OBJECT1 failed - major: Failure in tools library - minor: error in function - #002: (file name) line (number) in h5tools_dump_data(): H5Rget_obj_type3 H5R_OBJECT1 failed - major: Failure in tools library - minor: error in function diff --git a/tools/test/h5dump/errfiles/tattr-3.err b/tools/test/h5dump/errfiles/tattr-3.err deleted file mode 100644 index 7625965c453..00000000000 --- a/tools/test/h5dump/errfiles/tattr-3.err +++ /dev/null @@ -1,26 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Aopen(): unable to synchronously open attribute - major: Attribute - minor: Unable to create file - #001: (file name) line (number) in H5A__open_api_common(): unable to open attribute: 'attr' - major: Attribute - minor: Can't open object - #002: (file name) line (number) in H5A__open_common(): unable to open attribute: 'attr' - major: Attribute - minor: Can't open object - #003: (file name) line (number) in H5VL_attr_open(): attribute open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__attr_open(): attribute open failed - major: Virtual Object Layer - minor: Can't open object - #005: (file name) line (number) in H5VL__native_attr_open(): unable to open attribute: 'attr' - major: Attribute - minor: Can't open object - #006: (file name) line (number) in H5A__open(): unable to load attribute info from object header for attribute: 'attr' - major: Attribute - minor: Can't open object - #007: (file name) line (number) in H5O__attr_open_by_name(): can't locate attribute: 'attr' - major: Attribute - minor: Object not found -h5dump error: unable to open attribute "attr" diff --git a/tools/test/h5dump/errfiles/tattrregR.err b/tools/test/h5dump/errfiles/tattrregR.err deleted file mode 100644 index fa2014a1cf0..00000000000 --- a/tools/test/h5dump/errfiles/tattrregR.err +++ /dev/null @@ -1,21 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Rget_obj_type3(): unable to get object token - major: References - minor: Can't get value - #001: (file name) line (number) in H5R__get_obj_token(): NULL token size - major: References - minor: Unable to copy object -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Rget_obj_type3(): unable to get object token - major: References - minor: Can't get value - #001: (file name) line (number) in H5R__get_obj_token(): NULL token size - major: References - minor: Unable to copy object -H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): - #000: (file name) line (number) in h5tools_dump_data(): H5Rget_obj_type3 H5R_OBJECT1 failed - major: Failure in tools library - minor: error in function - #001: (file name) line (number) in h5tools_dump_data(): H5Rget_obj_type3 H5R_OBJECT1 failed - major: Failure in tools library - minor: error in function diff --git a/tools/test/h5dump/errfiles/tcomp-3.err b/tools/test/h5dump/errfiles/tcomp-3.err deleted file mode 100644 index 650df925421..00000000000 --- a/tools/test/h5dump/errfiles/tcomp-3.err +++ /dev/null @@ -1,31 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Topen2(): unable to open named datatype synchronously - major: Datatype - minor: Can't open object - #001: (file name) line (number) in H5T__open_api_common(): unable to open named datatype - major: Datatype - minor: Can't open object - #002: (file name) line (number) in H5VL_datatype_open(): datatype open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__datatype_open(): datatype open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_datatype_open(): unable to open named datatype - major: Datatype - minor: Can't open object - #005: (file name) line (number) in H5T__open_name(): not found - major: Datatype - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #009: (file name) line (number) in H5G__loc_find_cb(): object '#6632' doesn't exist - major: Symbol table - minor: Object not found diff --git a/tools/test/h5dump/errfiles/tdataregR.err b/tools/test/h5dump/errfiles/tdataregR.err deleted file mode 100644 index fa2014a1cf0..00000000000 --- a/tools/test/h5dump/errfiles/tdataregR.err +++ /dev/null @@ -1,21 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Rget_obj_type3(): unable to get object token - major: References - minor: Can't get value - #001: (file name) line (number) in H5R__get_obj_token(): NULL token size - major: References - minor: Unable to copy object -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Rget_obj_type3(): unable to get object token - major: References - minor: Can't get value - #001: (file name) line (number) in H5R__get_obj_token(): NULL token size - major: References - minor: Unable to copy object -H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): - #000: (file name) line (number) in h5tools_dump_data(): H5Rget_obj_type3 H5R_OBJECT1 failed - major: Failure in tools library - minor: error in function - #001: (file name) line (number) in h5tools_dump_data(): H5Rget_obj_type3 H5R_OBJECT1 failed - major: Failure in tools library - minor: error in function diff --git a/tools/test/h5dump/errfiles/tdset-2.err b/tools/test/h5dump/errfiles/tdset-2.err deleted file mode 100644 index 051c6775331..00000000000 --- a/tools/test/h5dump/errfiles/tdset-2.err +++ /dev/null @@ -1,57 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Dopen2(): unable to synchronously open dataset - major: Dataset - minor: Can't open object - #001: (file name) line (number) in H5D__open_api_common(): unable to open dataset - major: Dataset - minor: Can't open object - #002: (file name) line (number) in H5VL_dataset_open(): dataset open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__dataset_open(): dataset open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_dataset_open(): unable to open dataset - major: Dataset - minor: Can't open object - #005: (file name) line (number) in H5D__open_name(): not found - major: Dataset - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #009: (file name) line (number) in H5G__loc_find_cb(): object 'dset3' doesn't exist - major: Symbol table - minor: Object not found -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Lget_info2(): unable to get link info - major: Links - minor: Can't get value - #001: (file name) line (number) in H5VL_link_get(): link get failed - major: Virtual Object Layer - minor: Can't get value - #002: (file name) line (number) in H5VL__link_get(): link get failed - major: Virtual Object Layer - minor: Can't get value - #003: (file name) line (number) in H5VL__native_link_get(): unable to get link info - major: Links - minor: Object not found - #004: (file name) line (number) in H5L_get_info(): name doesn't exist - major: Links - minor: Object already exists - #005: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #006: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #007: (file name) line (number) in H5L__get_info_cb(): name doesn't exist - major: Links - minor: Object not found -h5dump error: unable to get link info from "dset3" diff --git a/tools/test/h5dump/errfiles/texceedsubblock.err b/tools/test/h5dump/errfiles/texceedsubblock.err deleted file mode 100644 index 4c87ab90f38..00000000000 --- a/tools/test/h5dump/errfiles/texceedsubblock.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: number of block dims (2) exceed dataset dims (1) diff --git a/tools/test/h5dump/errfiles/texceedsubcount.err b/tools/test/h5dump/errfiles/texceedsubcount.err deleted file mode 100644 index de1c9d1874e..00000000000 --- a/tools/test/h5dump/errfiles/texceedsubcount.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: number of count dims (2) exceed dataset dims (1) diff --git a/tools/test/h5dump/errfiles/texceedsubstart.err b/tools/test/h5dump/errfiles/texceedsubstart.err deleted file mode 100644 index 4555224a0f9..00000000000 --- a/tools/test/h5dump/errfiles/texceedsubstart.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: number of start dims (2) exceed dataset dims (1) diff --git a/tools/test/h5dump/errfiles/texceedsubstride.err b/tools/test/h5dump/errfiles/texceedsubstride.err deleted file mode 100644 index 32d57253879..00000000000 --- a/tools/test/h5dump/errfiles/texceedsubstride.err +++ /dev/null @@ -1 +0,0 @@ -h5dump error: number of stride dims (2) exceed dataset dims (1) diff --git a/tools/test/h5dump/errfiles/textlink.err b/tools/test/h5dump/errfiles/textlink.err deleted file mode 100644 index 04b129c535b..00000000000 --- a/tools/test/h5dump/errfiles/textlink.err +++ /dev/null @@ -1,74 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open external file, external link file name = 'filename' - major: Links - minor: Unable to open file -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open external file, external link file name = 'anotherfile' - major: Links - minor: Unable to open file diff --git a/tools/test/h5dump/errfiles/textlinkfar.err b/tools/test/h5dump/errfiles/textlinkfar.err deleted file mode 100644 index e5b81ce4197..00000000000 --- a/tools/test/h5dump/errfiles/textlinkfar.err +++ /dev/null @@ -1,255 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #012: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #013: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #014: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #015: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #016: (file name) line (number) in H5G__traverse_special(): symbolic link traversal failed - major: Links - minor: Link traversal failure - #017: (file name) line (number) in H5G__traverse_slink(): unable to follow symbolic link - major: Symbol table - minor: Object not found - #018: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #019: (file name) line (number) in H5G__traverse_slink_cb(): component not found - major: Symbol table - minor: Object not found -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #001: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #002: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #003: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #004: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #005: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #006: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #007: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #009: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #011: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #012: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #013: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #014: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #015: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #016: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #017: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #018: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #019: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #020: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #021: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #022: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #023: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #024: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #025: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #026: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #027: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #028: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #029: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #030: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #031: (file name) line (number) in H5G__traverse_special(): too many links - major: Links - minor: Too many soft links in path -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #001: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #002: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #003: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #004: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #005: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #006: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #007: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #009: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #011: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #012: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #013: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #014: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #015: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #016: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #017: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #018: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #019: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #020: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #021: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #022: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #023: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #024: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #025: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #026: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #027: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #028: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #029: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #030: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #031: (file name) line (number) in H5G__traverse_special(): too many links - major: Links - minor: Too many soft links in path diff --git a/tools/test/h5dump/errfiles/textlinksrc.err b/tools/test/h5dump/errfiles/textlinksrc.err deleted file mode 100644 index e5b81ce4197..00000000000 --- a/tools/test/h5dump/errfiles/textlinksrc.err +++ /dev/null @@ -1,255 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #012: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #013: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #014: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #015: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #016: (file name) line (number) in H5G__traverse_special(): symbolic link traversal failed - major: Links - minor: Link traversal failure - #017: (file name) line (number) in H5G__traverse_slink(): unable to follow symbolic link - major: Symbol table - minor: Object not found - #018: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #019: (file name) line (number) in H5G__traverse_slink_cb(): component not found - major: Symbol table - minor: Object not found -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #001: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #002: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #003: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #004: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #005: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #006: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #007: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #009: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #011: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #012: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #013: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #014: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #015: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #016: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #017: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #018: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #019: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #020: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #021: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #022: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #023: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #024: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #025: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #026: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #027: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #028: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #029: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #030: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #031: (file name) line (number) in H5G__traverse_special(): too many links - major: Links - minor: Too many soft links in path -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #001: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #002: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #003: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #004: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #005: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #006: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #007: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #009: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #011: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #012: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #013: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #014: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #015: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #016: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #017: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #018: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #019: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #020: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #021: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #022: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #023: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #024: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #025: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #026: (file name) line (number) in H5L__extern_traverse(): unable to open object - major: Links - minor: Can't open object - #027: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #028: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #029: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #030: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #031: (file name) line (number) in H5G__traverse_special(): too many links - major: Links - minor: Too many soft links in path diff --git a/tools/test/h5dump/errfiles/tgroup-2.err b/tools/test/h5dump/errfiles/tgroup-2.err deleted file mode 100644 index f9fa0cfd08c..00000000000 --- a/tools/test/h5dump/errfiles/tgroup-2.err +++ /dev/null @@ -1,32 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Gopen2(): unable to synchronously open group - major: Symbol table - minor: Unable to create file - #001: (file name) line (number) in H5G__open_api_common(): unable to open group - major: Symbol table - minor: Can't open object - #002: (file name) line (number) in H5VL_group_open(): group open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__group_open(): group open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_group_open(): unable to open group - major: Symbol table - minor: Can't open object - #005: (file name) line (number) in H5G__open_name(): group not found - major: Symbol table - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #009: (file name) line (number) in H5G__loc_find_cb(): object 'y' doesn't exist - major: Symbol table - minor: Object not found -h5dump error: unable to open group "/y" diff --git a/tools/test/h5dump/errfiles/torderlinks1.err b/tools/test/h5dump/errfiles/torderlinks1.err deleted file mode 100644 index 182fc31a9a5..00000000000 --- a/tools/test/h5dump/errfiles/torderlinks1.err +++ /dev/null @@ -1,37 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open external file, external link file name = 'fname' - major: Links - minor: Unable to open file diff --git a/tools/test/h5dump/errfiles/torderlinks2.err b/tools/test/h5dump/errfiles/torderlinks2.err deleted file mode 100644 index 182fc31a9a5..00000000000 --- a/tools/test/h5dump/errfiles/torderlinks2.err +++ /dev/null @@ -1,37 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Oopen(): unable to synchronously open object - major: Object header - minor: Can't open object - #001: (file name) line (number) in H5O__open_api_common(): unable to open object - major: Object header - minor: Can't open object - #002: (file name) line (number) in H5VL_object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__object_open(): object open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_object_open(): unable to open object by name - major: Object header - minor: Can't open object - #005: (file name) line (number) in H5O_open_name(): object not found - major: Object header - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): user-defined link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_ud(): traversal callback returned invalid ID - major: Symbol table - minor: Unable to find ID information (already closed?) - #011: (file name) line (number) in H5L__extern_traverse(): unable to open external file, external link file name = 'fname' - major: Links - minor: Unable to open file diff --git a/tools/test/h5dump/errfiles/tperror.err b/tools/test/h5dump/errfiles/tperror.err deleted file mode 100644 index 9e7972a8091..00000000000 --- a/tools/test/h5dump/errfiles/tperror.err +++ /dev/null @@ -1,57 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Dopen2(): unable to synchronously open dataset - major: Dataset - minor: Can't open object - #001: (file name) line (number) in H5D__open_api_common(): unable to open dataset - major: Dataset - minor: Can't open object - #002: (file name) line (number) in H5VL_dataset_open(): dataset open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__dataset_open(): dataset open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_dataset_open(): unable to open dataset - major: Dataset - minor: Can't open object - #005: (file name) line (number) in H5D__open_name(): not found - major: Dataset - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #009: (file name) line (number) in H5G__loc_find_cb(): object 'bogus' doesn't exist - major: Symbol table - minor: Object not found -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Lget_info2(): unable to get link info - major: Links - minor: Can't get value - #001: (file name) line (number) in H5VL_link_get(): link get failed - major: Virtual Object Layer - minor: Can't get value - #002: (file name) line (number) in H5VL__link_get(): link get failed - major: Virtual Object Layer - minor: Can't get value - #003: (file name) line (number) in H5VL__native_link_get(): unable to get link info - major: Links - minor: Object not found - #004: (file name) line (number) in H5L_get_info(): name doesn't exist - major: Links - minor: Object already exists - #005: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #006: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #007: (file name) line (number) in H5L__get_info_cb(): name doesn't exist - major: Links - minor: Object not found -h5dump error: unable to get link info from "bogus" diff --git a/tools/test/h5dump/errfiles/tqmarkfile.err b/tools/test/h5dump/errfiles/tqmarkfile.err deleted file mode 100644 index 4c3b2efd580..00000000000 --- a/tools/test/h5dump/errfiles/tqmarkfile.err +++ /dev/null @@ -1,33 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Dopen2(): not found - major: Dataset - minor: Object not found - #001: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #002: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #003: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #004: (file name) line (number) in H5G_loc_find_cb(): object 'Dataset1' doesn't exist - major: Symbol table - minor: Object not found -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Lget_info2(): unable to get link info - major: Symbol table - minor: Object not found - #001: (file name) line (number) in H5L_get_info(): name doesn't exist - major: Symbol table - minor: Object already exists - #002: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #003: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #004: (file name) line (number) in H5L_get_info_cb(): name doesn't exist - major: Symbol table - minor: Object not found -h5dump error: unable to get link info from "Dataset1" diff --git a/tools/test/h5dump/errfiles/tslink-D.err b/tools/test/h5dump/errfiles/tslink-D.err deleted file mode 100644 index f465f290306..00000000000 --- a/tools/test/h5dump/errfiles/tslink-D.err +++ /dev/null @@ -1,40 +0,0 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Dopen2(): unable to synchronously open dataset - major: Dataset - minor: Can't open object - #001: (file name) line (number) in H5D__open_api_common(): unable to open dataset - major: Dataset - minor: Can't open object - #002: (file name) line (number) in H5VL_dataset_open(): dataset open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__dataset_open(): dataset open failed - major: Virtual Object Layer - minor: Can't open object - #004: (file name) line (number) in H5VL__native_dataset_open(): unable to open dataset - major: Dataset - minor: Can't open object - #005: (file name) line (number) in H5D__open_name(): not found - major: Dataset - minor: Object not found - #006: (file name) line (number) in H5G_loc_find(): can't find object - major: Symbol table - minor: Object not found - #007: (file name) line (number) in H5G_traverse(): internal path traversal failed - major: Symbol table - minor: Object not found - #008: (file name) line (number) in H5G__traverse_real(): special link traversal failed - major: Links - minor: Link traversal failure - #009: (file name) line (number) in H5G__traverse_special(): symbolic link traversal failed - major: Links - minor: Link traversal failure - #010: (file name) line (number) in H5G__traverse_slink(): unable to follow symbolic link - major: Symbol table - minor: Object not found - #011: (file name) line (number) in H5G__traverse_real(): traversal operator failed - major: Symbol table - minor: Callback failed - #012: (file name) line (number) in H5G__traverse_slink_cb(): component not found - major: Symbol table - minor: Object not found diff --git a/tools/test/h5dump/expected/infinite_loop.ddl b/tools/test/h5dump/expected/infinite_loop.ddl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tools/test/h5dump/testfiles/3790_infinite_loop.h5 b/tools/test/h5dump/testfiles/3790_infinite_loop.h5 new file mode 100644 index 0000000000000000000000000000000000000000..0d3910a1a1638301afab1157bc65ff0ab63892fd GIT binary patch literal 829 zcmeD5aB<`1lHy_j0S*oZ76t(@6Gr@p0tIG>2#gPtPk=HQp>zk7Ucm%mFfxE31A_zu z!*8Ho20^I#=;}g(TwOsrVCKVUh$#rt0l^$)jfMa?1nL=F9RonD2xx$CK$actual 2>$actual_err - - # save actual and actual_err in case they are needed later. - cp $actual $actual_sav - STDOUT_FILTER $actual - cp $actual_err $actual_err_sav - STDERR_FILTER $actual_err - - # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ - -e 's/line [0-9]*/line (number)/' \ - -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ - -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ - -e 's/H5Eget_auto[1-2]*/H5Eget_auto(1 or 2)/' \ - -e 's/H5Eset_auto[1-2]*/H5Eset_auto(1 or 2)/' \ - $actual_err > $actual_ext - - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - echo " Expected result (*.ddl) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expect $actual; then - if $CMP $expect_err $actual_ext; then - echo " PASSED" - else - echo "*FAILED*" - echo " Expected result (*.err) differs from actual result (*.oerr)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect_err $actual_ext |sed 's/^/ /' - fi - else - echo "*FAILED*" - echo " Expected result (*.ddl) differs from actual result (*.out)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' - fi - - # Clean up output file - if test -z "$HDF5_NOCLEANUP"; then - rm -f $actual $actual_err $actual_sav $actual_err_sav - fi - -} - -# same as TOOLTEST4 but disables plugin filter loading -# silences extra error output on some platforms -# ADD_H5ERR_MASK_TEST -TOOLTEST5() { - - expect="$TESTDIR/$1" - expect_err="$TESTDIR/`basename $1 .ddl`.err" - actual="$TESTDIR/`basename $1 .ddl`.out" - actual_err="$TESTDIR/`basename $1 .ddl`.oerr" - actual_ext="$TESTDIR/`basename $1 .ddl`.ext" - actual_sav=${actual}-sav - actual_err_sav=${actual_err}-sav - shift - - # Run test. - TESTING $DUMPER $@ - ( - cd $TESTDIR - $ENVCMD $RUNSERIAL $DUMPER_BIN "$@" - ) >$actual 2>$actual_err - - # save actual and actual_err in case they are needed later. - cp $actual $actual_sav - STDOUT_FILTER $actual - cp $actual_err $actual_err_sav - STDERR_FILTER $actual_err - - # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ - -e 's/line [0-9]*/line (number)/' \ - -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ - -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ - -e 's/H5Eget_auto[1-2]*/H5Eget_auto(1 or 2)/' \ - -e 's/H5Eset_auto[1-2]*/H5Eset_auto(1 or 2)/' \ - $actual_err > $actual_ext - - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - echo " Expected result (*.ddl) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expect $actual; then - if $CMP $expect_err $actual_ext; then - echo " PASSED" - else - echo "*FAILED*" - echo " Expected result (*.err) differs from actual result (*.oerr)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect_err $actual_ext |sed 's/^/ /' - fi - else - echo "*FAILED*" - echo " Expected result (*.ddl) differs from actual result (*.out)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' - fi - # Clean up output file if test -z "$HDF5_NOCLEANUP"; then rm -f $actual $actual_err $actual_sav $actual_err_sav @@ -1096,6 +939,54 @@ GREPTEST2() fi } +# Call the h5dump tool and grep for a value but also compares the ddl output +# txttype ERRTXT greps test error output, otherwise greps test output +GREPTEST3() +{ + txttype=$1 + expectdata=$2 + expect="$TESTDIR/$3" + actual="$TESTDIR/`basename $3 .txt`.out" + actual_err="$TESTDIR/`basename $3 .ddl`.oerr" + actual_ext="$TESTDIR/`basename $3 .ddl`.ext" + shift + shift + shift + + # Run test. + TESTING $DUMPER $@ + ( + cd $TESTDIR + $ENVCMD $RUNSERIAL $DUMPER_BIN "$@" + ) >$actual 2>$actual_err + + if [ "$txttype" = "ERRTXT" ]; then + if $CMP $expect $actual; then + echo " PASSED" + else + echo "*FAILED*" + echo " Expected result (*.ddl) differs from actual result (*.out)" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + fi + $GREP "$expectdata" $actual_err > /dev/null + else + $GREP "$expectdata" $actual > /dev/null + fi + + if [ $? -eq 0 ]; then + echo " PASSED" + else + echo " FAILED" + nerrors="`expr $nerrors + 1`" + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + rm -f $actual $actual_err + fi +} + # Print a "SKIP" message SKIP() { TESTING $DUMPER $@ @@ -1209,12 +1100,12 @@ TOOLTEST tscalarstring.ddl --enable-error-stack tscalarstring.h5 # test for displaying groups TOOLTEST tgroup-1.ddl --enable-error-stack tgroup.h5 # test for displaying the selected groups -TOOLTEST4 tgroup-2.ddl --enable-error-stack --group=/g2 --group / -g /y tgroup.h5 +GREPTEST ERRTXT "h5dump error: unable to open group" tgroup-2.ddl --enable-error-stack --group=/g2 --group / -g /y tgroup.h5 # test for displaying simple space datasets TOOLTEST tdset-1.ddl --enable-error-stack tdset.h5 # test for displaying selected datasets -TOOLTEST4 tdset-2.ddl --enable-error-stack -H -d dset1 -d /dset2 --dataset=dset3 tdset.h5 +GREPTEST ERRTXT "h5dump error: unable to get link info from" tdset-2.ddl --enable-error-stack -H -d dset1 -d /dset2 --dataset=dset3 tdset.h5 # test for displaying attributes TOOLTEST tattr-1.ddl --enable-error-stack tattr.h5 @@ -1222,7 +1113,7 @@ TOOLTEST tattr-1.ddl --enable-error-stack tattr.h5 TOOLTEST tattr-2.ddl --enable-error-stack -a "/\/attr1" --attribute /attr4 --attribute=/attr5 tattr.h5 TOOLTEST tattr-2.ddl --enable-error-stack -N "/\/attr1" --any_path /attr4 --any_path=/attr5 tattr.h5 # test for header and error messages -TOOLTEST4 tattr-3.ddl --enable-error-stack --header -a /attr2 --attribute=/attr tattr.h5 +GREPTEST ERRTXT "h5dump error: unable to open attribute" tattr-3.ddl --enable-error-stack --header -a /attr2 --attribute=/attr tattr.h5 # test for displaying at least 9 attributes on root from a BE machine TOOLTEST tattr-4_be.ddl --enable-error-stack tattr4_be.h5 # test for displaying attributes in shared datatype (also in group and dataset) @@ -1236,7 +1127,7 @@ TOOLTEST tslink-2.ddl --enable-error-stack -l slink2 tslink.h5 TOOLTEST tslink-2.ddl --enable-error-stack -N slink2 tslink.h5 TOOLTEST tudlink-2.ddl --enable-error-stack -l udlink2 tudlink.h5 # test for displaying dangling soft links -TOOLTEST4 tslink-D.ddl --enable-error-stack -d /slink1 tslink.h5 +GREPTEST ERRTXT "component not found" tslink-D.ddl --enable-error-stack -d /slink1 tslink.h5 # tests for hard links TOOLTEST thlink-1.ddl --enable-error-stack thlink.h5 @@ -1253,7 +1144,7 @@ TOOLTEST tcomp-1.ddl --enable-error-stack tcompound.h5 TOOLTEST tcomp-2.ddl --enable-error-stack -t /type1 --datatype /type2 --datatype=/group1/type3 tcompound.h5 TOOLTEST tcomp-2.ddl --enable-error-stack -N /type1 --any_path /type2 --any_path=/group1/type3 tcompound.h5 # test for unnamed type -TOOLTEST4 tcomp-3.ddl --enable-error-stack -t /#6632 -g /group2 tcompound.h5 +GREPTEST ERRTXT "object '#6632' doesn't exist" tcomp-3.ddl --enable-error-stack -t /#6632 -g /group2 tcompound.h5 # test complicated compound datatype TOOLTEST tcomp-4.ddl --enable-error-stack tcompound_complex.h5 TOOLTEST tcompound_complex2.ddl --enable-error-stack tcompound_complex2.h5 @@ -1269,7 +1160,7 @@ TOOLTEST tnestcomp-1.ddl --enable-error-stack tnestedcomp.h5 TOOLTEST tnestedcmpddt.ddl --enable-error-stack tnestedcmpddt.h5 # test for options -TOOLTEST4 tall-1.ddl --enable-error-stack tall.h5 +GREPTEST ERRTXT "unable to open external file, external link file name" tall-1.ddl --enable-error-stack tall.h5 TOOLTEST tall-2.ddl --enable-error-stack --header -g /g1/g1.1 -a attr2 tall.h5 TOOLTEST tall-3.ddl --enable-error-stack -d /g2/dset2.1 -l /g1/g1.2/g1.2.1/slink tall.h5 TOOLTEST tall-3.ddl --enable-error-stack -N /g2/dset2.1 -N /g1/g1.2/g1.2.1/slink tall.h5 @@ -1311,7 +1202,7 @@ TOOLTEST tarray8.ddl --enable-error-stack tarray8.h5 # test for wildcards in filename (does not work with cmake) # inconsistent across platforms TOOLTEST3 tstarfile.ddl --enable-error-stack -H -d Dataset1 tarr*.h5 -#TOOLTEST4 tqmarkfile.ddl --enable-error-stack -H -d Dataset1 tarray?.h5 +#GREPTEST ERRTXT "unable to get link info from" tqmarkfile.ddl --enable-error-stack -H -d Dataset1 tarray?.h5 TOOLTEST tmultifile.ddl --enable-error-stack -H -d Dataset1 tarray2.h5 tarray3.h5 tarray4.h5 tarray5.h5 tarray6.h5 tarray7.h5 # test for files with empty data @@ -1329,13 +1220,13 @@ TOOLTEST tmulti.ddl --enable-error-stack --filedriver=multi tmulti TOOLTEST tlarge_objname.ddl --enable-error-stack -w157 tlarge_objname.h5 # test '-A' to suppress data but print attr's -TOOLTEST4 tall-2A.ddl --enable-error-stack -A tall.h5 +GREPTEST ERRTXT "unable to open external file, external link file name" tall-2A.ddl --enable-error-stack -A tall.h5 # test '-A' to suppress attr's but print data -TOOLTEST4 tall-2A0.ddl --enable-error-stack -A 0 tall.h5 +GREPTEST ERRTXT "unable to open external file, external link file name" tall-2A0.ddl --enable-error-stack -A 0 tall.h5 # test '-r' to print attributes in ASCII instead of decimal -TOOLTEST4 tall-2B.ddl --enable-error-stack -A -r tall.h5 +GREPTEST ERRTXT "unable to open external file, external link file name" tall-2B.ddl --enable-error-stack -A -r tall.h5 # test Subsetting TOOLTEST tall-4s.ddl --enable-error-stack --dataset=/g1/g1.1/dset1.1.1 --start=1,1 --stride=2,3 --count=3,2 --block=1,1 tall.h5 @@ -1365,7 +1256,7 @@ TOOLTEST tboot2B.ddl --enable-error-stack --superblock tfcontents2.h5 TOOLTEST file_space.ddl --enable-error-stack -B file_space.h5 # test -p with a non existing dataset -TOOLTEST4 tperror.ddl --enable-error-stack -p -d bogus tfcontents1.h5 +GREPTEST ERRTXT "h5dump error: unable to get link info from" tperror.ddl --enable-error-stack -p -d bogus tfcontents1.h5 # test for file contents TOOLTEST tcontents.ddl --enable-error-stack -n tfcontents1.h5 @@ -1414,10 +1305,10 @@ TOOLTEST tindicessub3.ddl --enable-error-stack -d 3d -s 0,1,2 -S 1,3,3 -c 2,2,2 TOOLTEST tindicessub4.ddl --enable-error-stack -d 4d -s 0,0,1,2 -c 2,2,3,2 -S 1,1,3,3 -k 1,1,2,2 taindices.h5 #Exceed the dimensions for subsetting -TOOLTEST texceedsubstart.ddl --enable-error-stack -d 1d -s 1,3 taindices.h5 -TOOLTEST texceedsubcount.ddl --enable-error-stack -d 1d -c 1,3 taindices.h5 -TOOLTEST texceedsubstride.ddl --enable-error-stack -d 1d -S 1,3 taindices.h5 -TOOLTEST texceedsubblock.ddl --enable-error-stack -d 1d -k 1,3 taindices.h5 +GREPTEST ERRTXT "exceed dataset dims" texceedsubstart.ddl --enable-error-stack -d 1d -s 1,3 taindices.h5 +GREPTEST ERRTXT "exceed dataset dims" texceedsubcount.ddl --enable-error-stack -d 1d -c 1,3 taindices.h5 +GREPTEST ERRTXT "exceed dataset dims" texceedsubstride.ddl --enable-error-stack -d 1d -S 1,3 taindices.h5 +GREPTEST ERRTXT "exceed dataset dims" texceedsubblock.ddl --enable-error-stack -d 1d -k 1,3 taindices.h5 # tests for filters @@ -1456,9 +1347,6 @@ TOOLTEST tbigdims.ddl --enable-error-stack -d dset4gb -s 4294967284 -c 22 tbigdi # hyperslab read TOOLTEST thyperslab.ddl --enable-error-stack thyperslab.h5 - -# - # test for displaying dataset and attribute of null space TOOLTEST tnullspace.ddl --enable-error-stack tnullspace.h5 TOOLTEST tgrpnullspace.ddl -p --enable-error-stack tgrpnullspace.h5 @@ -1539,18 +1427,18 @@ TOOLTEST torderattr3.ddl --enable-error-stack -H --sort_by=creation_order --sort TOOLTEST torderattr4.ddl --enable-error-stack -H --sort_by=creation_order --sort_order=descending torderattr.h5 # tests for link references and order -TOOLTEST4 torderlinks1.ddl --enable-error-stack --sort_by=name --sort_order=ascending tfcontents1.h5 -TOOLTEST4 torderlinks2.ddl --enable-error-stack --sort_by=name --sort_order=descending tfcontents1.h5 +GREPTEST3 ERRTXT "unable to open external file, external link file name = 'fname'" torderlinks1.ddl --enable-error-stack --sort_by=name --sort_order=ascending tfcontents1.h5 +GREPTEST3 ERRTXT "unable to open external file, external link file name = 'fname'" torderlinks2.ddl --enable-error-stack --sort_by=name --sort_order=descending tfcontents1.h5 # tests for floating point user defined printf format TOOLTEST tfpformat.ddl --enable-error-stack -m %.7f tfpformat.h5 # tests for traversal of external links -TOOLTEST4 textlinksrc.ddl --enable-error-stack textlinksrc.h5 -TOOLTEST4 textlinkfar.ddl --enable-error-stack textlinkfar.h5 +GREPTEST3 ERRTXT "Too many soft links in path" textlinksrc.ddl --enable-error-stack textlinksrc.h5 +GREPTEST3 ERRTXT "Too many soft links in path" textlinkfar.ddl --enable-error-stack textlinkfar.h5 # test for dangling external links -TOOLTEST4 textlink.ddl --enable-error-stack textlink.h5 +GREPTEST3 ERRTXT "unable to open external file, external link file name = 'anotherfile'" textlink.ddl --enable-error-stack textlink.h5 # test for error stack display (BZ2048) GREPTEST2 ERRTXT "filter plugins disabled" filter_fail.ddl --enable-error-stack filter_fail.h5 @@ -1559,10 +1447,13 @@ GREPTEST2 ERRTXT "filter plugins disabled" filter_fail.ddl --enable-error-stack TOOLTEST2 tall-6.exp --enable-error-stack -y -o tall-6.txt -d /g1/g1.1/dset1.1.1 tall.h5 # test for non-existing file -TOOLTEST3 non_existing.ddl --enable-error-stack tgroup.h5 non_existing.h5 +GREPTEST ERRTXT "unable to open file" non_existing.ddl --enable-error-stack tgroup.h5 non_existing.h5 + +# test to verify github issue #3790: infinite loop closing library +GREPTEST ERRTXT "unable to open file" infinite_loop.ddl 3790_infinite_loop.h5 # test to verify HDFFV-10333: error similar to H5O_attr_decode in the jira issue -TOOLTEST err_attr_dspace.ddl err_attr_dspace.h5 +GREPTEST ERRTXT "error getting attribute information" err_attr_dspace.ddl err_attr_dspace.h5 # test to verify HDFFV-9407: long double full precision #GREPTEST OUTTXT "1.123456789012345" t128bit_float.ddl -m %.35Lf t128bit_float.h5 diff --git a/tools/test/h5dump/testh5dumppbits.sh.in b/tools/test/h5dump/testh5dumppbits.sh.in index e90cc86e2ee..181dfb1b978 100644 --- a/tools/test/h5dump/testh5dumppbits.sh.in +++ b/tools/test/h5dump/testh5dumppbits.sh.in @@ -34,6 +34,7 @@ H5IMPORT_BIN=`pwd`/$H5IMPORT # The path of the h5import tool binary RM='rm -rf' CMP='cmp -s' DIFF='diff -c' +GREP='grep' CP='cp' DIRNAME='dirname' LS='ls' @@ -49,7 +50,6 @@ SRC_TOOLS="$srcdir/../.." SRC_H5LS_TESTFILES="$SRC_TOOLS/test/h5ls/testfiles" SRC_H5DUMP_TESTFILES="$SRC_TOOLS/test/h5dump/testfiles" SRC_H5DUMP_OUTFILES="$SRC_TOOLS/test/h5dump/expected" -SRC_H5DUMP_ERRORFILES="$SRC_TOOLS/test/h5dump/errfiles" SRC_H5DIFF_TESTFILES="$SRC_TOOLS/test/h5diff/testfiles" SRC_H5COPY_TESTFILES="$SRC_TOOLS/test/h5copy/testfiles" SRC_H5REPACK_TESTFILES="$SRC_TOOLS/test/h5repack/testfiles" @@ -133,26 +133,10 @@ $SRC_H5DUMP_OUTFILES/pbits/tpbitsSignedLongLong16.ddl $SRC_H5DUMP_OUTFILES/pbits/tpbitsUnsignedLongLong16.ddl " -LIST_ERROR_TEST_FILES=" -${SRC_H5DUMP_ERRORFILES}/pbits/tnofilename-with-packed-bits.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsCharLengthExceeded.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsCharOffsetExceeded.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsIncomplete.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsIntLengthExceeded.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsIntOffsetExceeded.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsLengthExceeded.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsLengthPositive.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsLongLengthExceeded.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsLongOffsetExceeded.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsMaxExceeded.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsOffsetExceeded.err -${SRC_H5DUMP_ERRORFILES}/pbits/tpbitsOffsetNegative.err -" - # # copy test files and expected output files from source dirs to test dir # -COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_OTHER_TEST_FILES $LIST_ERROR_TEST_FILES" +COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_OTHER_TEST_FILES" COPY_TESTFILES_TO_TESTDIR() { @@ -170,7 +154,7 @@ COPY_TESTFILES_TO_TESTDIR() INODE_SDIR=`$LS -i -d $SDIR | $AWK -F' ' '{print $1}'` INODE_DDIR=`$LS -i -d $TESTDIR | $AWK -F' ' '{print $1}'` if [ "$INODE_SDIR" != "$INODE_DDIR" ]; then - $CP -f $tstfile $TESTDIR + $CP -f $tstfile $TESTDIR if [ $? -ne 0 ]; then echo "Error: FAILED to copy $tstfile ." @@ -225,8 +209,8 @@ TOOLTEST() { # Run test. TESTING $DUMPER $@ ( - cd $TESTDIR - $RUNSERIAL $DUMPER_BIN "$@" + cd $TESTDIR + $RUNSERIAL $DUMPER_BIN "$@" ) >$actual 2>$actual_err # save actual and actual_err in case they are needed later. @@ -257,70 +241,17 @@ TOOLTEST() { } -# same as TOOLTEST1 but compares generated file to expected output -# and compares the generated data file to the expected data file -# used for the binary tests that expect a full path in -o without -b -TOOLTEST2() { - - expectdata="$TESTDIR/$1" - expect="$TESTDIR/`basename $1 .exp`.ddl" - actualdata="$TESTDIR/`basename $1 .exp`.txt" - actual="$TESTDIR/`basename $1 .exp`.out" - actual_err="$TESTDIR/`basename $1 .exp`.err" +# Call the h5dump tool and grep for a value +# txttype ERRTXT greps test error output, otherwise greps test output +GREPTEST() +{ + txttype=$1 + expectdata=$2 + expect="$TESTDIR/$3" + actual="$TESTDIR/`basename $3 .ddl`.out" + actual_err="$TESTDIR/`basename $3 .ddl`.oerr" + shift shift - - # Run test. - TESTING $DUMPER $@ - ( - cd $TESTDIR - $RUNSERIAL $DUMPER_BIN "$@" - ) >$actual 2>$actual_err - - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - echo " Expected result (*.ddl) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expect $actual; then - if [ ! -f $expectdata ]; then - # Create the expect data file if it doesn't yet exist. - echo " CREATED" - cp $actualdata $expectdata - echo " Expected data (*.exp) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expectdata $actualdata; then - echo " PASSED" - else - echo "*FAILED*" - echo " Expected datafile (*.exp) differs from actual datafile (*.txt)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expectdata $actualdata |sed 's/^/ /' - fi - else - echo "*FAILED*" - echo " Expected result (*.ddl) differs from actual result (*.out)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' - fi - - # Clean up output file - if test -z "$HDF5_NOCLEANUP"; then - rm -f $actual $actualdata $actual_err - fi - -} - -# same as TOOLTEST but filters error stack outp -# Extract file name, line number, version and thread IDs because they may be different -TOOLTEST3() { - - expect="$TESTDIR/$1" - actual="$TESTDIR/`basename $1 .ddl`.out" - actual_err="$TESTDIR/`basename $1 .ddl`.err" - actual_ext="$TESTDIR/`basename $1 .ddl`.ext" - actual_sav=${actual}-sav - actual_err_sav=${actual_err}-sav shift # Run test. @@ -330,178 +261,35 @@ TOOLTEST3() { $RUNSERIAL $DUMPER_BIN "$@" ) >$actual 2>$actual_err - # save actual and actual_err in case they are needed later. - cp $actual $actual_sav - STDOUT_FILTER $actual - cp $actual_err $actual_err_sav - STDERR_FILTER $actual_err - - # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ - -e 's/line [0-9]*/line (number)/' \ - -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ - -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ - -e 's/H5Eget_auto[1-2]*/H5Eget_auto(1 or 2)/' \ - -e 's/H5Eset_auto[1-2]*/H5Eset_auto(1 or 2)/' \ - $actual_err > $actual_ext - - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - echo " Expected result (*.ddl) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expect $actual; then - echo " PASSED" + if [ "$txttype" = "ERRTXT" ]; then + $GREP "$expectdata" $actual_err > /dev/null else - echo "*FAILED*" - echo " Expected result (*.ddl) differs from actual result (*.out)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' - fi - - # Clean up output file - if test -z "$HDF5_NOCLEANUP"; then - rm -f $actual $actual_err $actual_sav $actual_err_sav + $GREP "$expectdata" $actual > /dev/null fi -} - -# same as TOOLTEST3 but filters error stack output and compares to an error file -# Extract file name, line number, version and thread IDs because they may be different -TOOLTEST4() { - - expect="$TESTDIR/$1" - expect_err="$TESTDIR/`basename $1 .ddl`.err" - actual="$TESTDIR/`basename $1 .ddl`.out" - actual_err="$TESTDIR/`basename $1 .ddl`.oerr" - actual_ext="$TESTDIR/`basename $1 .ddl`.ext" - actual_sav=${actual}-sav - actual_err_sav=${actual_err}-sav - shift - - # Run test. - TESTING $DUMPER $@ - ( - cd $TESTDIR - $RUNSERIAL $DUMPER_BIN "$@" - ) >$actual 2>$actual_err - - # save actual and actual_err in case they are needed later. - cp $actual $actual_sav - STDOUT_FILTER $actual - cp $actual_err $actual_err_sav - STDERR_FILTER $actual_err - - # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ - -e 's/line [0-9]*/line (number)/' \ - -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ - -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ - -e 's/H5Eget_auto[1-2]*/H5Eget_auto(1 or 2)/' \ - -e 's/H5Eset_auto[1-2]*/H5Eset_auto(1 or 2)/' \ - $actual_err > $actual_ext - - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - echo " Expected result (*.ddl) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expect $actual; then - if $CMP $expect_err $actual_ext; then - echo " PASSED" - else - echo "*FAILED*" - echo " Expected result (*.err) differs from actual result (*.oerr)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect_err $actual_ext |sed 's/^/ /' - fi + if [ $? -eq 0 ]; then + echo " PASSED" else - echo "*FAILED*" - echo " Expected result (*.ddl) differs from actual result (*.out)" + echo " FAILED" nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' fi # Clean up output file if test -z "$HDF5_NOCLEANUP"; then - rm -f $actual $actual_err $actual_sav $actual_err_sav + rm -f $actual $actual_err fi - } # Print a "SKIP" message SKIP() { - TESTING $DUMPER $@ + TESTING $DUMPER $@ echo " -SKIP-" } -# Print a line-line message left justified in a field of 70 characters -# -PRINT_H5DIFF() { - SPACES=" " - echo " Running h5diff $* $SPACES" | cut -c1-70 | tr -d '\012' -} - - -# Call the h5diff tool -# -DIFFTEST() -{ - PRINT_H5DIFF $@ - ( - cd $TESTDIR - $RUNSERIAL $H5DIFF_BIN "$@" -q - ) - RET=$? - - if [ $RET != 0 ] ; then - echo "*FAILED*" - nerrors="`expr $nerrors + 1`" - else - echo " PASSED" - fi - -} - -# Print a line-line message left justified in a field of 70 characters -# beginning with the word "Verifying". -# -PRINT_H5IMPORT() { - SPACES=" " - echo " Running h5import $* $SPACES" | cut -c1-70 | tr -d '\012' -} - -# Call the h5import tool -# -IMPORTTEST() -{ - # remove the output hdf5 file if it exists - hdf5_file="$TESTDIR/$5" - if [ -f $hdf5_file ]; then - rm -f $hdf5_file - fi - - PRINT_H5IMPORT $@ - ( - cd $TESTDIR - $RUNSERIAL $H5IMPORT_BIN "$@" - ) - RET=$? - - if [ $RET != 0 ] ; then - echo "*FAILED*" - nerrors="`expr $nerrors + 1`" - else - echo " PASSED" - fi -} - ############################################################################## ############################################################################## -### T H E T E S T S ### +### T H E T E S T S ### ############################################################################## ############################################################################## # prepare for test @@ -511,7 +299,7 @@ COPY_TESTFILES_TO_TESTDIR # test failure handling # Missing file name -TOOLTEST tnofilename-with-packed-bits.ddl --enable-error-stack +GREPTEST ERRTXT "missing file name" tnofilename-with-packed-bits.ddl --enable-error-stack # Limits: # Maximum number of packed bits is 8 (for now). # Maximum integer size is 64 (for now). @@ -570,23 +358,23 @@ TOOLTEST tpbitsCompound.ddl --enable-error-stack -d /dset1 -M 0,1,1,1 tcompound. TOOLTEST tpbitsArray.ddl --enable-error-stack -d /Dataset1 -M 0,1,1,1 tarray1.h5 # Test Error handling. # Too many packed bits requested. Max is 8 for now. -TOOLTEST tpbitsMaxExceeded.ddl --enable-error-stack -d /DS08BITS -M 0,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1 packedbits.h5 +GREPTEST ERRTXT "Too many masks requested" tpbitsMaxExceeded.ddl --enable-error-stack -d /DS08BITS -M 0,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1 packedbits.h5 # Offset too large. Max is 7 (8-1) for now. -TOOLTEST tpbitsOffsetExceeded.ddl --enable-error-stack -d /DS08BITS -M 64,1 packedbits.h5 +GREPTEST ERRTXT "must be between 0 and 63" tpbitsOffsetExceeded.ddl --enable-error-stack -d /DS08BITS -M 64,1 packedbits.h5 TOOLTEST tpbitsCharOffsetExceeded.ddl --enable-error-stack -d /DS08BITS -M 8,1 packedbits.h5 TOOLTEST tpbitsIntOffsetExceeded.ddl --enable-error-stack -d /DS16BITS -M 16,1 packedbits.h5 TOOLTEST tpbitsLongOffsetExceeded.ddl --enable-error-stack -d /DS32BITS -M 32,1 packedbits.h5 # Bad offset, must not be negative. -TOOLTEST tpbitsOffsetNegative.ddl --enable-error-stack -d /DS08BITS -M -1,1 packedbits.h5 +GREPTEST ERRTXT "Bad mask list" tpbitsOffsetNegative.ddl --enable-error-stack -d /DS08BITS -M -1,1 packedbits.h5 # Bad length, must not be positive. -TOOLTEST tpbitsLengthPositive.ddl --enable-error-stack -d /DS08BITS -M 4,0 packedbits.h5 +GREPTEST ERRTXT "must be positive" tpbitsLengthPositive.ddl --enable-error-stack -d /DS08BITS -M 4,0 packedbits.h5 # Offset+Length is too large. Max is 8 for now. -TOOLTEST tpbitsLengthExceeded.ddl --enable-error-stack -d /DS08BITS -M 37,28 packedbits.h5 +GREPTEST ERRTXT "too large" tpbitsLengthExceeded.ddl --enable-error-stack -d /DS08BITS -M 37,28 packedbits.h5 TOOLTEST tpbitsCharLengthExceeded.ddl --enable-error-stack -d /DS08BITS -M 2,7 packedbits.h5 TOOLTEST tpbitsIntLengthExceeded.ddl --enable-error-stack -d /DS16BITS -M 10,7 packedbits.h5 TOOLTEST tpbitsLongLengthExceeded.ddl --enable-error-stack -d /DS32BITS -M 26,7 packedbits.h5 # Incomplete pair of packed bits request. -TOOLTEST tpbitsIncomplete.ddl --enable-error-stack -d /DS08BITS -M 0,2,2,1,0,2,2, packedbits.h5 +GREPTEST ERRTXT "Bad mask list" tpbitsIncomplete.ddl --enable-error-stack -d /DS08BITS -M 0,2,2,1,0,2,2, packedbits.h5 # Clean up temporary files/directories CLEAN_TESTFILES_AND_TESTDIR diff --git a/tools/test/h5dump/testh5dumpvds.sh.in b/tools/test/h5dump/testh5dumpvds.sh.in index 2bd38dc8a32..9c992303d67 100644 --- a/tools/test/h5dump/testh5dumpvds.sh.in +++ b/tools/test/h5dump/testh5dumpvds.sh.in @@ -49,7 +49,6 @@ SRC_TOOLS="$srcdir/../.." SRC_H5LS_TESTFILES="$SRC_TOOLS/test/h5ls/testfiles" SRC_H5DUMP_TESTFILES="$SRC_TOOLS/test/h5dump/testfiles" SRC_H5DUMP_OUTFILES="$SRC_TOOLS/test/h5dump/expected" -SRC_H5DUMP_ERRORFILES="$srcdir/errfiles" SRC_H5DIFF_TESTFILES="$SRC_TOOLS/test/h5diff/testfiles" SRC_H5COPY_TESTFILES="$SRC_TOOLS/test/h5copy/testfiles" SRC_H5REPACK_TESTFILES="$SRC_TOOLS/test/h5repack/testfiles" @@ -125,13 +124,10 @@ $SRC_H5DUMP_OUTFILES/vds/vds_layout-eiger.ddl $SRC_H5DUMP_OUTFILES/vds/vds_layout-maxmin.ddl " -LIST_ERROR_TEST_FILES=" -" - # # copy test files and expected output files from source dirs to test dir # -COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_OTHER_TEST_FILES $LIST_ERROR_TEST_FILES" +COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_OTHER_TEST_FILES" COPY_TESTFILES_TO_TESTDIR() { @@ -237,246 +233,12 @@ TOOLTEST() { } -# same as TOOLTEST1 but compares generated file to expected output -# and compares the generated data file to the expected data file -# used for the binary tests that expect a full path in -o without -b -TOOLTEST2() { - - expectdata="$TESTDIR/$1" - expect="$TESTDIR/`basename $1 .exp`.ddl" - actualdata="$TESTDIR/`basename $1 .exp`.txt" - actual="$TESTDIR/`basename $1 .exp`.out" - actual_err="$TESTDIR/`basename $1 .exp`.err" - shift - - # Run test. - TESTING $DUMPER $@ - ( - cd $TESTDIR - $RUNSERIAL $DUMPER_BIN "$@" - ) >$actual 2>$actual_err - cat $actual_err >> $actual - - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - echo " Expected result (*.ddl) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expect $actual; then - if [ ! -f $expectdata ]; then - # Create the expect data file if it doesn't yet exist. - echo " CREATED" - cp $actualdata $expectdata - echo " Expected data (*.exp) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expectdata $actualdata; then - echo " PASSED" - else - echo "*FAILED*" - echo " Expected datafile (*.exp) differs from actual datafile (*.txt)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expectdata $actualdata |sed 's/^/ /' - fi - else - echo "*FAILED*" - echo " Expected result (*.ddl) differs from actual result (*.out)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' - fi - - # Clean up output file - if test -z "$HDF5_NOCLEANUP"; then - rm -f $actual $actualdata $actual_err - fi - -} - -# same as TOOLTEST but filters error stack outp -# Extract file name, line number, version and thread IDs because they may be different -TOOLTEST3() { - - expect="$TESTDIR/$1" - actual="$TESTDIR/`basename $1 .ddl`.out" - actual_err="$TESTDIR/`basename $1 .ddl`.err" - actual_ext="$TESTDIR/`basename $1 .ddl`.ext" - actual_sav=${actual}-sav - actual_err_sav=${actual_err}-sav - shift - - # Run test. - TESTING $DUMPER $@ - ( - cd $TESTDIR - $RUNSERIAL $DUMPER_BIN "$@" - ) >$actual 2>$actual_err - - # save actual and actual_err in case they are needed later. - cp $actual $actual_sav - STDOUT_FILTER $actual - cp $actual_err $actual_err_sav - STDERR_FILTER $actual_err - - # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ - -e 's/line [0-9]*/line (number)/' \ - -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ - -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ - -e 's/H5Eget_auto[1-2]*/H5Eget_auto(1 or 2)/' \ - -e 's/H5Eset_auto[1-2]*/H5Eset_auto(1 or 2)/' \ - $actual_err > $actual_ext - cat $actual_ext >> $actual - - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - echo " Expected result (*.ddl) missing" - nerrors="`expr $nerrors + 1`" - elif $CMP $expect $actual; then - echo " PASSED" - else - echo "*FAILED*" - echo " Expected result (*.ddl) differs from actual result (*.out)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' - fi - - # Clean up output file - if test -z "$HDF5_NOCLEANUP"; then - rm -f $actual $actual_err $actual_sav $actual_err_sav - fi - -} - -# same as TOOLTEST3 but filters error stack output and compares to an error file -# Extract file name, line number, version and thread IDs because they may be different -TOOLTEST4() { - - expect="$TESTDIR/$1" - expect_err="$TESTDIR/`basename $1 .ddl`.err" - actual="$TESTDIR/`basename $1 .ddl`.out" - actual_err="$TESTDIR/`basename $1 .ddl`.oerr" - actual_ext="$TESTDIR/`basename $1 .ddl`.ext" - actual_sav=${actual}-sav - actual_err_sav=${actual_err}-sav - shift - - # Run test. - TESTING $DUMPER $@ - ( - cd $TESTDIR - $RUNSERIAL $DUMPER_BIN "$@" - ) >$actual 2>$actual_err - - # save actual and actual_err in case they are needed later. - cp $actual $actual_sav - STDOUT_FILTER $actual - cp $actual_err $actual_err_sav - STDERR_FILTER $actual_err - - # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ - -e 's/line [0-9]*/line (number)/' \ - -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ - -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ - -e 's/H5Eget_auto[1-2]*/H5Eget_auto(1 or 2)/' \ - -e 's/H5Eset_auto[1-2]*/H5Eset_auto(1 or 2)/' \ - $actual_err > $actual_ext - #cat $actual_ext >> $actual - - if [ ! -f $expect ]; then - # Create the expect file if it doesn't yet exist. - echo " CREATED" - cp $actual $expect - elif $CMP $expect $actual; then - if $CMP $expect_err $actual_ext; then - echo " PASSED" - else - echo "*FAILED*" - echo " Expected result (*.err) differs from actual result (*.oerr)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect_err $actual_ext |sed 's/^/ /' - fi - else - echo "*FAILED*" - echo " Expected result (*.ddl) differs from actual result (*.out)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' - fi - - # Clean up output file - if test -z "$HDF5_NOCLEANUP"; then - rm -f $actual $actual_err $actual_sav $actual_err_sav - fi -} - # Print a "SKIP" message SKIP() { TESTING $DUMPER $@ echo " -SKIP-" } -# Print a line-line message left justified in a field of 70 characters -# -PRINT_H5DIFF() { - SPACES=" " - echo " Running h5diff $* $SPACES" | cut -c1-70 | tr -d '\012' -} - - -# Call the h5diff tool -# -DIFFTEST() -{ - PRINT_H5DIFF $@ - ( - cd $TESTDIR - $RUNSERIAL $H5DIFF_BIN "$@" -q - ) - RET=$? - - if [ $RET != 0 ] ; then - echo "*FAILED*" - nerrors="`expr $nerrors + 1`" - else - echo " PASSED" - fi -} - -# Print a line-line message left justified in a field of 70 characters -# beginning with the word "Verifying". -# -PRINT_H5IMPORT() { - SPACES=" " - echo " Running h5import $* $SPACES" | cut -c1-70 | tr -d '\012' -} - -# Call the h5import tool -# -IMPORTTEST() -{ - # remove the output hdf5 file if it exists - hdf5_file="$TESTDIR/$5" - if [ -f $hdf5_file ]; then - rm -f $hdf5_file - fi - - PRINT_H5IMPORT $@ - ( - cd $TESTDIR - $RUNSERIAL $H5IMPORT_BIN "$@" - ) - RET=$? - - if [ $RET != 0 ] ; then - echo "*FAILED*" - nerrors="`expr $nerrors + 1`" - else - echo " PASSED" - fi -} - ############################################################################## ############################################################################## diff --git a/tools/test/h5format_convert/CMakeTests.cmake b/tools/test/h5format_convert/CMakeTests.cmake index 49b9bbc26c5..cb0879f3993 100644 --- a/tools/test/h5format_convert/CMakeTests.cmake +++ b/tools/test/h5format_convert/CMakeTests.cmake @@ -45,13 +45,10 @@ old_h5fc_ext2_sf.ddl old_h5fc_ext3_isf.ddl h5fc_v_err.ddl - h5fc_v_err.ddl.err ) set (HDF5_REFERENCE_ERR_FILES - h5fc_d_file.ddl.err h5fc_dname.err h5fc_nonexistfile.ddl.err - h5fc_nonexistdset_file.ddl.err ) set (HDF5_REFERENCE_TEST_FILES h5fc_non_v3.h5 @@ -266,7 +263,6 @@ set_tests_properties (H5FC_CHECK_IDX-${testname}-clean-objects PROPERTIES FIXTURES_CLEANUP clear_H5FC-${testname} ) - add_test ( NAME H5FC-${testname}-tmpfile COMMAND ${CMAKE_COMMAND} -E copy_if_different ${HDF5_TOOLS_TEST_H5FC_SOURCE_DIR}/testfiles/${testfile} ./testfiles/${testname}-tmp.h5 @@ -440,17 +436,20 @@ # h5format_convert nonexist.h5 (no options, file does not exist) ADD_H5_OUTPUT (h5fc_help h5fc_help.ddl 0 "" --help) ADD_H5_OUTPUT (h5fc_nooption h5fc_nooption.ddl 1 "") +# ADD_H5_MASK_OUTPUT (h5fc_nooption h5fc_nooption.ddl 1 "" "") ADD_H5_OUTPUT (h5fc_nonexistfile h5fc_nonexistfile.ddl 1 "" nonexist.h5) +# ADD_H5_MASK_OUTPUT (h5fc_nonexistfile h5fc_nonexistfile.ddl 1 "unable to open file" "" nonexist.h5) # # # h5format_convert -d old_h5fc_ext_none.h5 (just -d option, file exists) # h5format_convert --dname old_h5fc_ext_none.h5 (just --dname option, file exists) # h5format_convert --dname (just --dname option) # h5format_convert --dname=nonexist old_h5fc_ext_none.h5 (dataset does not exist, file exists) - ADD_H5_OUTPUT (h5fc_d_file-d h5fc_d_file.ddl 1 old_h5fc_ext_none.h5 -d) - ADD_H5_OUTPUT (h5fc_d_file h5fc_d_file.ddl 1 old_h5fc_ext_none.h5 --dname) + ADD_H5_MASK_OUTPUT (h5fc_d_file-d h5fc_d_file.ddl 1 "missing file name" old_h5fc_ext_none.h5 -d) + ADD_H5_MASK_OUTPUT (h5fc_d_file h5fc_d_file.ddl 1 "missing file name" old_h5fc_ext_none.h5 --dname) ADD_H5_OUTPUT (h5fc_dname h5fc_dname.ddl 1 "" --dname) - ADD_H5_OUTPUT (h5fc_nonexistdset_file h5fc_nonexistdset_file.ddl 1 old_h5fc_ext_none.h5 --dname=nonexist) +# ADD_H5_MASK_OUTPUT (h5fc_dname h5fc_dname.ddl 1 "missing file name" "" --dname) + ADD_H5_MASK_OUTPUT (h5fc_nonexistdset_file h5fc_nonexistdset_file.ddl 1 "unable to open dataset" old_h5fc_ext_none.h5 --dname=nonexist) # # # diff --git a/tools/test/h5format_convert/testh5fc.sh.in b/tools/test/h5format_convert/testh5fc.sh.in index 756156ebb02..6b75248f3c3 100644 --- a/tools/test/h5format_convert/testh5fc.sh.in +++ b/tools/test/h5format_convert/testh5fc.sh.in @@ -43,6 +43,7 @@ H5DUMP_BIN=`pwd`/$H5DUMP # The path of the h5dump tool binary DIRNAME='dirname' LS='ls' AWK='awk' +GREP='grep' nerrors=0 verbose=yes @@ -219,7 +220,6 @@ TESTING() { TOOLTEST_OUT() { # Prepare expected and actual output expect="$TESTDIR/$1" - expect_err="$TESTDIR/`basename $1 .ddl`.err" actual="$TESTDIR/`basename $1 .ddl`.out" actual_err="$TESTDIR/`basename $1 .ddl`.out.err" actual_sav=${actual}-sav @@ -283,7 +283,7 @@ TOOLTEST_MASK_OUT() { STDERR_FILTER $actual_err # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ + sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ @@ -351,6 +351,42 @@ TOOLTEST_ERR() { $RM $actual $actual_err $actual_sav $actual_err_sav fi } +# Same as TOOLTEST_OUT except only grep error output +TOOLTEST_GREP() { + # Prepare expected and actual output + expect="$TESTDIR/$1" + expected=$2 + actual="$TESTDIR/`basename $1 .ddl`.out" + actual_err="$TESTDIR/`basename $1 .ddl`.out.err" + actual_sav=${actual}-sav + actual_err_sav=${actual_err}-sav + testfile="`basename $1 .ddl`-tmp.h5" + + # Run test. + TESTING $FORMCONV $3 $4 $5 $6 $2 + ( + cd $TESTDIR + $RUNSERIAL $FORMCONV_BIN $3 $4 $5 $6 $TFILE + ) >$actual 2>$actual_err + cp $actual $actual_sav + cp $actual_err $actual_err_sav + + # Compare output + $GREP "$expectdata" $actual_err > /dev/null + if [ $? -eq 0 ]; then + echo " PASSED" + else + echo "*FAILED*" + echo " Expected error message not found in actual output" + nerrors="`expr $nerrors + 1`" + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + $RM $actual $actual_err + $RM $actual $actual_err $actual_sav $actual_err_sav + fi +} # To check that the tool exits success, no output # Assume all short options @@ -462,6 +498,7 @@ COPY_TESTFILES_TO_TESTDIR TOOLTEST_OUT h5fc_help.ddl '' --help TOOLTEST_OUT h5fc_nooption.ddl '' TOOLTEST_ERR h5fc_nonexistfile.ddl nonexist.h5 +#TOOLTEST_GREP h5fc_nonexistfile.ddl "unable to open file" # # # h5format_convert -d old_h5fc_ext_none.h5 (just -d option, file exists) diff --git a/tools/test/h5ls/CMakeTests.cmake b/tools/test/h5ls/CMakeTests.cmake index 2aefdb65715..e47c254f465 100644 --- a/tools/test/h5ls/CMakeTests.cmake +++ b/tools/test/h5ls/CMakeTests.cmake @@ -51,13 +51,6 @@ tudlink.h5 tvldtypes1.h5 ) - - set (LIST_ERR_TEST_FILES - nosuchfile.err - textlinksrc-nodangle-1.err - tgroup-1.err - ) - set (LIST_OTHER_TEST_FILES help-1.ls help-2.ls @@ -136,9 +129,6 @@ foreach (listothers ${LIST_OTHER_TEST_FILES}) HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/expected/${listothers}" "${PROJECT_BINARY_DIR}/testfiles/${listothers}" "h5ls_files") endforeach () - foreach (listerrfiles ${LIST_ERR_TEST_FILES}) - HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/errfiles/${listerrfiles}" "${PROJECT_BINARY_DIR}/testfiles/${listerrfiles}" "h5ls_files") - endforeach () add_custom_target(h5ls_files ALL COMMENT "Copying files needed by h5ls tests" DEPENDS ${h5ls_files_list}) ############################################################################## diff --git a/tools/test/h5ls/errfiles/nosuchfile.err b/tools/test/h5ls/errfiles/nosuchfile.err deleted file mode 100644 index 8c4ee420101..00000000000 --- a/tools/test/h5ls/errfiles/nosuchfile.err +++ /dev/null @@ -1 +0,0 @@ -nosuchfile.h5: unable to open file diff --git a/tools/test/h5ls/errfiles/textlinksrc-nodangle-1.err b/tools/test/h5ls/errfiles/textlinksrc-nodangle-1.err deleted file mode 100644 index 8991fc13ba0..00000000000 --- a/tools/test/h5ls/errfiles/textlinksrc-nodangle-1.err +++ /dev/null @@ -1,2 +0,0 @@ -Error: --no-dangling-links must be used along with --follow-symlinks option! - diff --git a/tools/test/h5ls/errfiles/tgroup-1.err b/tools/test/h5ls/errfiles/tgroup-1.err deleted file mode 100644 index ba4cf078f29..00000000000 --- a/tools/test/h5ls/errfiles/tgroup-1.err +++ /dev/null @@ -1,2 +0,0 @@ -Error: 'recursive' option not compatible with 'group info' option! - diff --git a/tools/test/h5ls/testh5ls.sh.in b/tools/test/h5ls/testh5ls.sh.in index e8ea342fda6..78844cfc654 100644 --- a/tools/test/h5ls/testh5ls.sh.in +++ b/tools/test/h5ls/testh5ls.sh.in @@ -51,7 +51,6 @@ SRC_H5REPACK_TESTFILES="$SRC_TOOLS/test/h5repack/testfiles" SRC_H5JAM_TESTFILES="$SRC_TOOLS/test/h5jam/testfiles" SRC_H5STAT_TESTFILES="$SRC_TOOLS/test/h5stat/testfiles" SRC_H5IMPORT_TESTFILES="$SRC_TOOLS/test/h5import/testfiles" -SRC_H5LS_ERRFILES="$SRC_TOOLS/test/h5ls/errfiles" SRC_H5LS_OUTFILES="$SRC_TOOLS/test/h5ls/expected" TESTDIR=./tmp @@ -95,12 +94,6 @@ $SRC_H5DUMP_TESTFILES/tvldtypes1.h5 $SRC_H5LS_TESTFILES/tdset_idx.h5 " -LIST_ERROR_TEST_FILES=" -$SRC_H5LS_ERRFILES/nosuchfile.err -$SRC_H5LS_ERRFILES/textlinksrc-nodangle-1.err -$SRC_H5LS_ERRFILES/tgroup-1.err -" - LIST_OTHER_TEST_FILES=" $SRC_H5LS_OUTFILES/help-1.ls $SRC_H5LS_OUTFILES/help-2.ls @@ -240,7 +233,6 @@ TESTING() { # $2 and on -- argument for the h5ls tool TOOLTEST() { expect="$TESTDIR/$1" - expect_err="$TESTDIR/`basename $1 .ls`.err" actual="$TESTDIR/`basename $1 .ls`.out" actual_err="$TESTDIR/`basename $1 .ls`.out.err" actual_sav=${actual}-sav diff --git a/tools/test/h5repack/expected/h5repack_layout.h5-dset2_chunk_20x10-errstk.tst b/tools/test/h5repack/expected/h5repack_layout.h5-dset2_chunk_20x10-errstk.tst index 3d9f0c2d22d..97ef7370395 100644 --- a/tools/test/h5repack/expected/h5repack_layout.h5-dset2_chunk_20x10-errstk.tst +++ b/tools/test/h5repack/expected/h5repack_layout.h5-dset2_chunk_20x10-errstk.tst @@ -1,4 +1,4 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5Dcreate2(): unable to synchronously create dataset major: Dataset minor: Unable to create file @@ -44,7 +44,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #014: (file name) line (number) in H5D__chunk_construct(): dimensionality of chunks doesn't match the dataspace major: Dataset minor: Bad value -H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): +H5tools-DIAG: Error detected in HDF5:tools (version (number)): #000: (file name) line (number) in do_copy_objects(): H5Dcreate2 failed major: Failure in tools library minor: function info diff --git a/tools/test/h5repack/h5repack.sh.in b/tools/test/h5repack/h5repack.sh.in index db8e603a88d..b7d46e3c8d5 100644 --- a/tools/test/h5repack/h5repack.sh.in +++ b/tools/test/h5repack/h5repack.sh.in @@ -1061,7 +1061,7 @@ TOOLTESTM() { cp $actual_err $actual_err_sav # Extract file name, line number, version and thread IDs because they may be different - sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ + sed -e 's/ thread [0-9]*//' -e 's/: .*\.c /: (file name) /' \ -e 's/line [0-9]*/line (number)/' \ -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ diff --git a/tools/test/h5stat/CMakeTests.cmake b/tools/test/h5stat/CMakeTests.cmake index ed45e9302ab..f6287406ee8 100644 --- a/tools/test/h5stat/CMakeTests.cmake +++ b/tools/test/h5stat/CMakeTests.cmake @@ -52,17 +52,6 @@ h5stat_numattrs3 h5stat_numattrs4 ) - set (HDF5_REFERENCE_ERR_FILES - h5stat_err_refcount - h5stat_err_old_layout - h5stat_err_old_fill - h5stat_err1_dims - h5stat_err1_links - h5stat_err1_numattrs - h5stat_err2_numattrs - h5stat_notexist - h5stat_nofile - ) set (HDF5_REFERENCE_TEST_FILES h5stat_err_refcount.h5 h5stat_err_old_layout.h5 @@ -78,10 +67,6 @@ HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/expected/${ddl_file}.ddl" "${PROJECT_BINARY_DIR}/${ddl_file}.ddl" "h5stat_files") endforeach () - foreach (h5_file ${HDF5_REFERENCE_ERR_FILES}) - HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/expected/${h5_file}.err" "${PROJECT_BINARY_DIR}/${h5_file}.err" "h5stat_files") - endforeach () - foreach (h5_file ${HDF5_REFERENCE_TEST_FILES}) HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/testfiles/${h5_file}" "${PROJECT_BINARY_DIR}/${h5_file}" "h5stat_files") endforeach () @@ -122,7 +107,7 @@ endif () endmacro () - macro (ADD_H5_ERR_TEST resultfile resultcode) + macro (ADD_H5_ERR_TEST resultfile resultcode errtext) # If using memchecker add tests without using scripts if (HDF5_USING_ANALYSIS_TOOL) add_test (NAME H5STAT-${resultfile} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ ${ARGN}) @@ -135,13 +120,44 @@ COMMAND "${CMAKE_COMMAND}" -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" -D "TEST_PROGRAM=$" - -D "TEST_ARGS=${ARGN}" + -D "TEST_ARGS:STRING=${ARGN}" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" -D "TEST_OUTPUT=${resultfile}.out" -D "TEST_EXPECT=${resultcode}" -D "TEST_REFERENCE=${resultfile}.mty" - -D "TEST_ERRREF=${resultfile}.err" - -P "${HDF_RESOURCES_DIR}/runTest.cmake" + -D "TEST_ERRREF=${errtext}" + -D "TEST_SKIP_COMPARE=true" + -P "${HDF_RESOURCES_DIR}/grepTest.cmake" + ) + endif () + set_tests_properties (H5STAT-${resultfile} PROPERTIES + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}" + ) + if ("H5STAT-${resultfile}" MATCHES "${HDF5_DISABLE_TESTS_REGEX}") + set_tests_properties (H5STAT-${resultfile} PROPERTIES DISABLED true) + endif () + endmacro () + + macro (ADD_H5_CMP_TEST resultfile resultcode errtext) + # If using memchecker add tests without using scripts + if (HDF5_USING_ANALYSIS_TOOL) + add_test (NAME H5STAT-${resultfile} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ ${ARGN}) + if (${resultcode}) + set_tests_properties (H5STAT-${resultfile} PROPERTIES WILL_FAIL "true") + endif () + else (HDF5_USING_ANALYSIS_TOOL) + add_test ( + NAME H5STAT-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS:STRING=${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_OUTPUT=${resultfile}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}.ddl" + -D "TEST_ERRREF=${errtext}" + -P "${HDF_RESOURCES_DIR}/grepTest.cmake" ) endif () set_tests_properties (H5STAT-${resultfile} PROPERTIES @@ -163,8 +179,8 @@ ADD_H5_TEST (h5stat_help2 0 --help) # Test when h5stat a file that does not exist - ADD_H5_TEST (h5stat_notexist 1 notexist.h5) - ADD_H5_TEST (h5stat_nofile 1 '') + ADD_H5_ERR_TEST (h5stat_notexist 1 "unable to open file" notexist.h5) + ADD_H5_CMP_TEST (h5stat_nofile 1 "missing file name" '') # Test file with groups, compressed datasets, user-applied filters, etc. # h5stat_filters.h5 is a copy of ../../testfiles/tfilters.h5 as of release 1.8.0-alpha4 @@ -191,7 +207,7 @@ # -g -l 8 # --links=8 # --links=20 -g - ADD_H5_ERR_TEST (h5stat_err1_links 1 -l 0 h5stat_threshold.h5) + ADD_H5_ERR_TEST (h5stat_err1_links 1 "Invalid threshold for small groups" -l 0 h5stat_threshold.h5) ADD_H5_TEST (h5stat_links1 0 -g -l 8 h5stat_threshold.h5) ADD_H5_TEST (h5stat_links2 0 --links=8 h5stat_threshold.h5) ADD_H5_TEST (h5stat_links3 0 --links=20 -g h5stat_threshold.h5) @@ -206,7 +222,7 @@ # -d --dims=-1 (incorrect threshold value) # -gd -m 5 # -d --di=15 - ADD_H5_ERR_TEST (h5stat_err1_dims 1 -d --dims=-1 h5stat_threshold.h5) + ADD_H5_ERR_TEST (h5stat_err1_dims 1 "Invalid threshold for small datasets" -d --dims=-1 h5stat_threshold.h5) ADD_H5_TEST (h5stat_dims1 0 -gd -m 5 h5stat_threshold.h5) ADD_H5_TEST (h5stat_dims2 0 -d --dims=15 h5stat_threshold.h5) # @@ -216,8 +232,8 @@ # -AS -a 10 # -a 1 # -A --numattrs=25 - ADD_H5_ERR_TEST (h5stat_err1_numattrs 1 -a -2 h5stat_threshold.h5) - ADD_H5_ERR_TEST (h5stat_err2_numattrs 1 --numattrs h5stat_threshold.h5) + ADD_H5_ERR_TEST (h5stat_err1_numattrs 1 "Invalid threshold for small # of attributes" -a -2 h5stat_threshold.h5) + ADD_H5_ERR_TEST (h5stat_err2_numattrs 1 "Invalid threshold for small # of attributes" --numattrs h5stat_threshold.h5) ADD_H5_TEST (h5stat_numattrs1 0 -AS -a 10 h5stat_threshold.h5) ADD_H5_TEST (h5stat_numattrs2 0 -a 1 h5stat_threshold.h5) ADD_H5_TEST (h5stat_numattrs3 0 -A --numattrs=25 h5stat_threshold.h5) @@ -229,8 +245,8 @@ # Tests to verify HDFFV-10333: # h5stat_err_refcount.h5 is generated by h5stat_gentest.c # h5stat_err_old_layout.h5 and h5stat_err_old_fill.h5: see explanation in h5stat_gentest.c - ADD_H5_TEST (h5stat_err_refcount 1 h5stat_err_refcount.h5) - ADD_H5_TEST (h5stat_err_old_layout 1 h5stat_err_old_layout.h5) - ADD_H5_TEST (h5stat_err_old_fill 1 h5stat_err_old_fill.h5) + ADD_H5_CMP_TEST (h5stat_err_refcount 1 "unable to traverse objects" h5stat_err_refcount.h5) + ADD_H5_CMP_TEST (h5stat_err_old_layout 1 "unable to traverse objects" h5stat_err_old_layout.h5) + ADD_H5_CMP_TEST (h5stat_err_old_fill 1 "unable to traverse objects" h5stat_err_old_fill.h5) # # diff --git a/tools/test/h5stat/expected/h5stat_err1_dims.err b/tools/test/h5stat/expected/h5stat_err1_dims.err deleted file mode 100644 index 86d375b6324..00000000000 --- a/tools/test/h5stat/expected/h5stat_err1_dims.err +++ /dev/null @@ -1 +0,0 @@ -h5stat error: Invalid threshold for small datasets diff --git a/tools/test/h5stat/expected/h5stat_err1_links.err b/tools/test/h5stat/expected/h5stat_err1_links.err deleted file mode 100644 index d43207c1374..00000000000 --- a/tools/test/h5stat/expected/h5stat_err1_links.err +++ /dev/null @@ -1 +0,0 @@ -h5stat error: Invalid threshold for small groups diff --git a/tools/test/h5stat/expected/h5stat_err1_numattrs.err b/tools/test/h5stat/expected/h5stat_err1_numattrs.err deleted file mode 100644 index 01b6c18ed66..00000000000 --- a/tools/test/h5stat/expected/h5stat_err1_numattrs.err +++ /dev/null @@ -1 +0,0 @@ -h5stat error: Invalid threshold for small # of attributes diff --git a/tools/test/h5stat/expected/h5stat_err2_numattrs.err b/tools/test/h5stat/expected/h5stat_err2_numattrs.err deleted file mode 100644 index 01b6c18ed66..00000000000 --- a/tools/test/h5stat/expected/h5stat_err2_numattrs.err +++ /dev/null @@ -1 +0,0 @@ -h5stat error: Invalid threshold for small # of attributes diff --git a/tools/test/h5stat/expected/h5stat_err_old_fill.err b/tools/test/h5stat/expected/h5stat_err_old_fill.err deleted file mode 100644 index 8b886d29810..00000000000 --- a/tools/test/h5stat/expected/h5stat_err_old_fill.err +++ /dev/null @@ -1 +0,0 @@ -h5stat error: unable to traverse objects/links in file "h5stat_err_old_fill.h5" diff --git a/tools/test/h5stat/expected/h5stat_err_old_layout.err b/tools/test/h5stat/expected/h5stat_err_old_layout.err deleted file mode 100644 index 7aa2fa7d000..00000000000 --- a/tools/test/h5stat/expected/h5stat_err_old_layout.err +++ /dev/null @@ -1 +0,0 @@ -h5stat error: unable to traverse objects/links in file "h5stat_err_old_layout.h5" diff --git a/tools/test/h5stat/expected/h5stat_err_refcount.err b/tools/test/h5stat/expected/h5stat_err_refcount.err deleted file mode 100644 index d176996a286..00000000000 --- a/tools/test/h5stat/expected/h5stat_err_refcount.err +++ /dev/null @@ -1 +0,0 @@ -h5stat error: unable to traverse objects/links in file "h5stat_err_refcount.h5" diff --git a/tools/test/h5stat/expected/h5stat_nofile.err b/tools/test/h5stat/expected/h5stat_nofile.err deleted file mode 100644 index 3b7e97949a4..00000000000 --- a/tools/test/h5stat/expected/h5stat_nofile.err +++ /dev/null @@ -1 +0,0 @@ -h5stat error: missing file name diff --git a/tools/test/h5stat/expected/h5stat_notexist.err b/tools/test/h5stat/expected/h5stat_notexist.err deleted file mode 100644 index c1d9e5432cc..00000000000 --- a/tools/test/h5stat/expected/h5stat_notexist.err +++ /dev/null @@ -1 +0,0 @@ -h5stat error: unable to open file "notexist.h5" diff --git a/tools/test/h5stat/testh5stat.sh.in b/tools/test/h5stat/testh5stat.sh.in index 1d732c600ae..bc48494f59b 100644 --- a/tools/test/h5stat/testh5stat.sh.in +++ b/tools/test/h5stat/testh5stat.sh.in @@ -33,6 +33,7 @@ CP='cp' DIRNAME='dirname' LS='ls' AWK='awk' +GREP='grep' nerrors=0 verbose=yes @@ -74,18 +75,6 @@ $SRC_H5STAT_TESTFILES/h5stat_idx.h5 $SRC_H5STAT_TESTFILES/h5stat_threshold.h5 " -LIST_ERR_TEST_FILES=" -$SRC_H5STAT_OUTFILES/h5stat_err_refcount.err -$SRC_H5STAT_OUTFILES/h5stat_err_old_layout.err -$SRC_H5STAT_OUTFILES/h5stat_err_old_fill.err -$SRC_H5STAT_OUTFILES/h5stat_err1_links.err -$SRC_H5STAT_OUTFILES/h5stat_err1_dims.err -$SRC_H5STAT_OUTFILES/h5stat_err1_numattrs.err -$SRC_H5STAT_OUTFILES/h5stat_err2_numattrs.err -$SRC_H5STAT_OUTFILES/h5stat_notexist.err -$SRC_H5STAT_OUTFILES/h5stat_nofile.err -" - LIST_OTHER_TEST_FILES=" $SRC_H5STAT_OUTFILES/h5stat_err_refcount.ddl $SRC_H5STAT_OUTFILES/h5stat_err_old_layout.ddl @@ -123,7 +112,7 @@ $SRC_H5STAT_OUTFILES/h5stat_numattrs4.ddl # # copy test files and expected output files from source dirs to test dir # -COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_ERR_TEST_FILES $LIST_OTHER_TEST_FILES" +COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_OTHER_TEST_FILES" COPY_TESTFILES_TO_TESTDIR() { @@ -187,7 +176,6 @@ TESTING() { # TOOLTEST() { expect="$TESTDIR/$1" - expect_err="$TESTDIR/`basename $1 .ddl`.err" actual="$TESTDIR/`basename $1 .ddl`.out" actual_err="$TESTDIR/`basename $1 .ddl`.out.err" actual_sav=${actual}-sav @@ -207,17 +195,7 @@ TOOLTEST() { cp $actual_err $actual_err_sav STDERR_FILTER $actual_err - if [ ! -f $expect ]; then - # Compare error files if the expect file doesn't exist. - if $CMP $expect_err $actual_err; then - echo " PASSED" - else - echo "*FAILED*" - echo " Expected result (*.err) differs from actual result (*.out.err)" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect_err $actual_err |sed 's/^/ /' - fi - elif $CMP $expect $actual; then + if $CMP $expect $actual; then echo " PASSED" else echo "*FAILED*" @@ -233,6 +211,52 @@ TOOLTEST() { } +# Call the h5stat tool and grep for a value +# txttype ERRTXT greps test error output, otherwise greps test output +GREPTEST() +{ + txttype=$1 + expectdata=$2 + expect="$TESTDIR/$3" + actual="$TESTDIR/`basename $1 .ddl`.out" + actual_err="$TESTDIR/`basename $1 .ddl`.out.err" + shift + shift + shift + if [ "$1" = -i ]; then + inputfile=$2 + fi + + if [ "$3" = -o ]; then + outputfile=$4 + fi + + TESTING $STAT $@ + ( + cd $TESTDIR + $RUNSERIAL $STAT_BIN $@ + ) >$actual 2>$actual_err + RET=$? + + if [ "$txttype" = "ERRTXT" ]; then + $GREP "$expectdata" $actual_err > /dev/null + else + $GREP "$expectdata" $actual > /dev/null + fi + + if [ $? -eq 0 ]; then + echo " PASSED" + else + echo " FAILED" + nerrors="`expr $nerrors + 1`" + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + rm -f $actual $actual_err + fi +} + # Print a "SKIP" message SKIP() { TESTING $STAT $@ @@ -282,7 +306,7 @@ TOOLTEST h5stat_idx.ddl h5stat_idx.h5 # -g -l 8 # --links=8 # --links=20 -g -TOOLTEST h5stat_err1_links.ddl -l 0 h5stat_threshold.h5 +GREPTEST ERRTXT "Invalid threshold for small groups" h5stat_err1_links.ddl -l 0 h5stat_threshold.h5 TOOLTEST h5stat_links1.ddl -g -l 8 h5stat_threshold.h5 TOOLTEST h5stat_links2.ddl --links=8 h5stat_threshold.h5 TOOLTEST h5stat_links3.ddl --links=20 -g h5stat_threshold.h5 @@ -297,7 +321,7 @@ TOOLTEST h5stat_links5.ddl -g -l 40000 h5stat_newgrat.h5 # -d --dims=-1 (incorrect threshold value) # -gd -m 5 # -d --di=15 -TOOLTEST h5stat_err1_dims.ddl -d --dims=-1 h5stat_threshold.h5 +GREPTEST ERRTXT "Invalid threshold for small datasets" h5stat_err1_dims.ddl -d --dims=-1 h5stat_threshold.h5 TOOLTEST h5stat_dims1.ddl -gd -m 5 h5stat_threshold.h5 TOOLTEST h5stat_dims2.ddl -d --dims=15 h5stat_threshold.h5 # @@ -307,8 +331,8 @@ TOOLTEST h5stat_dims2.ddl -d --dims=15 h5stat_threshold.h5 # -AS -a 10 # -a 1 # -A --numattrs=25 -TOOLTEST h5stat_err1_numattrs.ddl -a -2 h5stat_threshold.h5 -TOOLTEST h5stat_err2_numattrs.ddl --numattrs h5stat_threshold.h5 +GREPTEST ERRTXT "Invalid threshold for small # of attributes" h5stat_err1_numattrs.ddl -a -2 h5stat_threshold.h5 +GREPTEST ERRTXT "Invalid threshold for small # of attributes" h5stat_err2_numattrs.ddl --numattrs h5stat_threshold.h5 TOOLTEST h5stat_numattrs1.ddl -AS -a 10 h5stat_threshold.h5 TOOLTEST h5stat_numattrs2.ddl -a 1 h5stat_threshold.h5 TOOLTEST h5stat_numattrs3.ddl -A --numattrs=25 h5stat_threshold.h5 diff --git a/tools/test/misc/CMakeTestsClear.cmake b/tools/test/misc/CMakeTestsClear.cmake index 63f1d6a66c1..9ad371bd5ac 100644 --- a/tools/test/misc/CMakeTestsClear.cmake +++ b/tools/test/misc/CMakeTestsClear.cmake @@ -58,10 +58,6 @@ h5clear_user_less_after_size.ddl h5clear_user_less_before_size.ddl ) - set (HDF5_REFERENCE_ERR_FILES - h5clear_no_mdc_image.err - h5clear_open_fail.err - ) foreach (h5_file ${HDF5_TEST_FILES} ${HDF5_SEC2_TEST_FILES}) HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/testfiles/${h5_file}" "${PROJECT_BINARY_DIR}/testfiles/${h5_file}" "h5clear_files") @@ -69,9 +65,6 @@ foreach (h5_file ${HDF5_REFERENCE_TEST_FILES}) HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/expected/${h5_file}" "${PROJECT_BINARY_DIR}/testfiles/${h5_file}" "h5clear_files") endforeach () - foreach (h5_file ${HDF5_REFERENCE_ERR_FILES}) - HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/expected/${h5_file}" "${PROJECT_BINARY_DIR}/testfiles/${h5_file}" "h5clear_files") - endforeach () # make second copy of h5clear_sec2.h5 foreach (h5_file ${HDF5_SEC2_TEST_FILES}) HDFTEST_COPY_FILE("${PROJECT_SOURCE_DIR}/testfiles/${h5_file}" "${PROJECT_BINARY_DIR}/testfiles/orig_${h5_file}" "h5clear_files") diff --git a/tools/test/misc/expected/h5clear_missing_file.err b/tools/test/misc/expected/h5clear_missing_file.err deleted file mode 100644 index ea21b76eee1..00000000000 --- a/tools/test/misc/expected/h5clear_missing_file.err +++ /dev/null @@ -1 +0,0 @@ -h5clear error: missing file name diff --git a/tools/test/misc/expected/h5clear_no_mdc_image.err b/tools/test/misc/expected/h5clear_no_mdc_image.err deleted file mode 100644 index f5acd71b479..00000000000 --- a/tools/test/misc/expected/h5clear_no_mdc_image.err +++ /dev/null @@ -1 +0,0 @@ -h5clear warning: No cache image in the file diff --git a/tools/test/misc/expected/h5clear_open_fail.err b/tools/test/misc/expected/h5clear_open_fail.err deleted file mode 100644 index 895ecd4298b..00000000000 --- a/tools/test/misc/expected/h5clear_open_fail.err +++ /dev/null @@ -1 +0,0 @@ -h5clear error: h5tools_fopen diff --git a/tools/test/misc/testh5clear.sh.in b/tools/test/misc/testh5clear.sh.in index 2306d589938..b97509415e2 100644 --- a/tools/test/misc/testh5clear.sh.in +++ b/tools/test/misc/testh5clear.sh.in @@ -30,6 +30,7 @@ CP='cp' DIRNAME='dirname' LS='ls' AWK='awk' +GREP='grep' SUCCEED=0 FAIL=1 @@ -61,8 +62,6 @@ test -d $TESTDIR || mkdir -p $TESTDIR # copy test files and expected output files from source dirs to test dir # COPY_TESTFILES=" -$SRC_H5CLEAR_OUTFILES/h5clear_open_fail.err -$SRC_H5CLEAR_OUTFILES/h5clear_no_mdc_image.err $SRC_H5CLEAR_OUTFILES/h5clear_usage.ddl $SRC_H5CLEAR_OUTFILES/h5clear_missing_file.ddl $SRC_H5CLEAR_OUTFILES/h5clear_status_noclose_after_size.ddl @@ -178,7 +177,6 @@ TOOLTEST_OUT() { expected=$5 # Prepare expected and actual output expect="$TESTDIR/$expected" - expect_err="$TESTDIR/`basename $expected .ddl`.err" actual="$TESTDIR/`basename $expected .ddl`.out" actual_err="$TESTDIR/`basename $expected .ddl`.out.err" actual_sav=${actual}-sav @@ -201,18 +199,16 @@ TOOLTEST_OUT() { $RM $actual $actual_err $actual_sav $actual_err_sav fi } -# same as TOOLTEST_OUT just compare stderr +# same as TOOLTEST_OUT just grep stderr TOOLTEST_ERR() { fname=$1 - option1=$2 - option2=$3 - option3=$4 - expected=$5 + expected=$2 + option1=$3 + option2=$4 + option3=$5 # Prepare expected and actual output - expect_err="$TESTDIR/$expected" - expect="$TESTDIR/`basename $expected .err`.ddl" - actual="$TESTDIR/`basename $expected .err`.out" - actual_err="$TESTDIR/`basename $expected .err`.out.err" + actual="$TESTDIR/`basename $fname .h5`.out" + actual_err="$TESTDIR/`basename $fname .h5`.out.err" actual_sav=${actual}-sav actual_err_sav=${actual_err}-sav @@ -225,9 +221,15 @@ TOOLTEST_ERR() { cp $actual $actual_sav cp $actual_err $actual_err_sav - # Compare output - COMPARE_OUT $expect_err $actual_err - + # grep output + $GREP "$expected" $actual_err > /dev/null + if test $? -eq 0; then + echo "PASSED" + else + echo "*FAILED*" + echo " Expected text not found in actual result (*.out.err)" + nerrors="`expr $nerrors + 1`" + fi # Clean up output file if test -z "$HDF5_NOCLEANUP"; then $RM $actual $actual_err $actual_sav $actual_err_sav @@ -305,11 +307,11 @@ TOOLTEST_OUT "" "" "" "" h5clear_usage.ddl TOOLTEST_OUT junk.h5 "" "" "" h5clear_usage.ddl TOOLTEST_OUT orig_h5clear_sec2_v3.h5 "" "" "" h5clear_usage.ddl TOOLTEST_OUT "" -m "" "" h5clear_missing_file.ddl -TOOLTEST_ERR junk.h5 -s "" "" h5clear_open_fail.err +TOOLTEST_ERR junk.h5 "h5clear error" -s "" "" TOOLTEST_OUT "" -m -s "" h5clear_missing_file.ddl -TOOLTEST_ERR junk.h5 -m -s "" h5clear_open_fail.err -TOOLTEST_ERR orig_h5clear_sec2_v2.h5 -m "" "" h5clear_no_mdc_image.err -TOOLTEST_ERR orig_h5clear_sec2_v0.h5 -s -m "" h5clear_no_mdc_image.err +TOOLTEST_ERR junk.h5 "h5clear error" -m -s "" +TOOLTEST_ERR orig_h5clear_sec2_v2.h5 "h5clear warning" -m "" "" +TOOLTEST_ERR orig_h5clear_sec2_v0.h5 "h5clear warning" -s -m "" # # # The following are tests to verify the expected exit code from h5clear: @@ -339,8 +341,8 @@ TOOLTEST h5clear_sec2_v0.h5 -l -m $FAIL # # # h5clear_mdc_image.h5 already has cache image removed earlier, verify the expected warning from h5clear: -TOOLTEST_ERR mod_h5clear_mdc_image.h5 -m "" "" h5clear_no_mdc_image.err -TOOLTEST_ERR mod_h5clear_mdc_image.h5 -s -m "" h5clear_no_mdc_image.err +TOOLTEST_ERR mod_h5clear_mdc_image.h5 "h5clear warning" -m "" "" +TOOLTEST_ERR mod_h5clear_mdc_image.h5 "h5clear warning" -s -m "" # # # @@ -378,7 +380,7 @@ OPEN_CHK h5clear_sec2_v2.h5 $SUCCEED # "h5clear -s --increment=0 h5clear_status_noclose.h5" (clear status_flag, EOA = MAX(EOA, EOF) + 0) # (no output, check exit code) # "h5clear --filesize h5clear_status_noclose_user.h5" (print EOA/EOF after the last action) -TOOLTEST_ERR h5clear_status_noclose.h5 --filesize "" "" h5clear_open_fail.err +TOOLTEST_ERR h5clear_status_noclose.h5 "h5clear error:" --filesize "" "" TOOLTEST h5clear_status_noclose.h5 -s --increment=0 $SUCCEED TOOLTEST_OUT h5clear_status_noclose.h5 --filesize "" "" h5clear_status_noclose_after_size.ddl #