diff --git a/.github/workflows/h5py.yml b/.github/workflows/h5py.yml index cf29c7e2166..35a92fc21b7 100644 --- a/.github/workflows/h5py.yml +++ b/.github/workflows/h5py.yml @@ -24,7 +24,7 @@ jobs: - name: Run a multi-line script run: | - sed -i 's/hdf5@1.8.4:1.14/hdf5@1.8.4:/g' \ + sed -i 's/hdf5@1.10.4:1.14/hdf5@1.10.4:/g' \ ./spack/var/spack/repos/builtin/packages/py-h5py/package.py . ./spack/share/spack/setup-env.sh ./spack/bin/spack spec py-h5py@master+mpi ^hdf5@develop-1.15 diff --git a/CMakeLists.txt b/CMakeLists.txt index aa78f51ce5e..1fbaad21cbe 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 #----------------------------------------------------------------------------- @@ -1147,40 +1183,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/release b/bin/release index 25b450efb86..f72390cda08 100755 --- a/bin/release +++ b/bin/release @@ -455,7 +455,7 @@ cp -p Makefile.dist Makefile # Update README.md and release_docs/RELEASE.txt with release information in # line 1. -for f in README.md release_docs/RELEASE.txt; do +for f in README.md release_docs/RELEASE.txt release_docs/NEWSLETTER.txt; do echo "HDF5 version $VERS released on $release_date" >$f.x sed -e 1d $f >>$f.x mv $f.x $f diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 15d96f607fb..56e91cddc93 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -434,6 +434,7 @@ endif () if (MINGW OR NOT WINDOWS) foreach (other_test HAVE_ATTRIBUTE + HAVE_BUILTIN_EXPECT SYSTEM_SCOPE_THREADS HAVE_SOCKLEN_T ) diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 586032bf269..af80d0b545b 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -328,6 +328,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/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/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 b22c8ea21a4..04bb2f25116 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' @@ -2417,6 +2417,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 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/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 c71d1615b57..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,9 +703,11 @@ 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 +/** @page LBCompiling Compiling HDF5 Applications Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics
@@ -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,13 +1018,13 @@ For example, on Unix the log files will be in: There are log files for the configure, test, and build.
-Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics +Previous Chapter \ref LBQuizAnswers - Next Chapter \ref LBTraining -@page LBTraining Training Videos Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics -
-Training Videos +*/ + +/ref LBTraining
Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics diff --git a/doxygen/dox/TrainingVideos.dox b/doxygen/dox/TrainingVideos.dox new file mode 100644 index 00000000000..8e15176f9f4 --- /dev/null +++ b/doxygen/dox/TrainingVideos.dox @@ -0,0 +1,50 @@ +/** @page LBTraining Training Videos +Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics +
+ +
+ + + + +
[**HDF5 Introduction**](https://youtu.be/S74Kc8QYDac)
+ +## Core Topics + + + + + + + + + + + + + + + + + +
[**Data Model and Basic Usage, Core Topic #1**](https://youtu.be/vKuthH200eI)[**Datasets, Core Topic #2**](https://youtu.be/2oDXgecMMfo)[**Attributes, Core Topic #3**](https://youtu.be/d_P6LhmzmWQ)
[**Groups and Links, Core Topic #4**](https://youtu.be/29J_FxPEDxo)[**Discovering File Structure, Core Topic #5**](https://youtu.be/rIl1Gz8zh-8)[**Partial IO, Core Topic #6**](https://youtu.be/RuzwPCFGBRE)
[**Compound Datatype, Core Topic #7**](https://youtu.be/NXWwjrPdACY)
+ +## Advanced Topics: + + + + + + + +
[**Dataset Storage Layouts, Advanced Topic #1**](https://youtu.be/mOTpu5KDpj8)[**Using Compression and Filters, Advanced Topic #2**](https://youtu.be/TvnDV-U9T4k)[**Using Command Line Tools, Advanced Topic #3**](https://youtu.be/CPIO1lmRkdM)
+ +
+Previous Chapter \ref LBCompiling + +Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics + +*/ + + + diff --git a/doxygen/examples/H5.format.html b/doxygen/examples/H5.format.html index 9b2c0651d79..023c19d7c19 100644 --- a/doxygen/examples/H5.format.html +++ b/doxygen/examples/H5.format.html @@ -1432,7 +1432,7 @@

Address of Member File N

-

This field Specifies the virtual address at which the member file starts.

+

This field specifies the virtual address at which the member file starts.

N is the number of member files.

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/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/NEWSLETTER.txt b/release_docs/NEWSLETTER.txt index 55b7dcd8203..3884718c6ed 100644 --- a/release_docs/NEWSLETTER.txt +++ b/release_docs/NEWSLETTER.txt @@ -1,18 +1,9 @@ -Release of HDF5 1.14.4 Library and Tools is now available from the HDF5 Releases page. +HDF5 version 1.15.0 currently under development -This is a maintenance release with a few changes and updates: +Features included for the next major release: ---------------------------------------------------------------------------- -* Added support for _Float16 16-bit floating-point datatype - - Support for the 16-bit floating-point _Float16 C type has been added to - HDF5. On platforms where this type is available, this can enable more - efficient storage of floating-point data when an application doesn't - need the precision of larger floating-point datatypes. It can also allow - for improved performance when converting between 16-bit floating-point - data and data of another HDF5 datatype. - - (GitHub #4065, #2154) +* ---------------------------------------------------------------------------- Please see the full release notes for detailed information regarding this release, diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 64ec15a48b1..9218e108e82 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -754,12 +754,25 @@ Bug Fixes since HDF5-1.14.0 release Library ------- - - 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. + - 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 + - Fixed many (future) CVE issues A partner organization corrected many potential security issues, which diff --git a/release_docs/RELEASE_PROCESS.md b/release_docs/RELEASE_PROCESS.md new file mode 100644 index 00000000000..e371dab6a42 --- /dev/null +++ b/release_docs/RELEASE_PROCESS.md @@ -0,0 +1,163 @@ +# Release Process + +## Objective: +Release a new version of HDF software, which corrects defects, adds functionality, improves maintainability, and/or ports it to new operational environments. + +## Description (General): +At regularly scheduled intervals throughout each year, The HDF Group releases a new version of each of its maintained/core software products and corresponding documentation set. This is referred to as a maintenance release. The main purpose of a maintenance release is to address defects reported against previous releases of the software, to port the software to new operating environments, and to improve maintainability by way of refactoring code and improving documentation. A maintenance release may also include new functionality in any of the product's components. + +Depending on the software being released, there may be specific guidelines that are followed or steps that are performed in addition to the 'standard' maintenance release procedure - in such a case, product-specific tabs are provided within the page to view information specific to only that product. + +## Description (HDF5): +Twice each year, The HDF Group releases a new version of the HDF5 C, C++, and Fortran libraries and command line utilities and associated documentation set. This is referred to as a maintenance release of HDF5. The main purpose of a maintenance release is to address defects reported against previous releases of the software, to port HDF5 to new operating environments, and to improve maintainability by way of refactoring code and improving documentation. A maintenance release may also include new functionality in the C, C++, and Fortran libraries and/or command line utilities if requested and/or funded by the user community and/or The HDF Group's customers. The new features included in a maintenance release expand the feature set only and do not change the HDF5 file format, with the exception of addressing critical defects that corrupt data. + +Maintenance releases are always backward compatible with regards to the HDF5 file format, meaning that: +- New libraries and command line utilities can access HDF5 files created by the previous versions of the libraries. + +Maintenance releases are always forward compatible with regards to the HDF5 file format, meaning that: +- HDF5 libraries and command line utilities can access files created by future maintenance versions of the library. +Note that maintenance releases are NOT guaranteed to be interface-compatible, meaning that, on occasion, application source code will need updated and re-compiled against a new maintenance release when the interface changes. Interface changes are only made when absolutely necessary as deemed by the HDF5 product manager(s), and interface compatibility reports are published with each release to inform customers and users of any incompatibilities in the interface. + +For more information on the HDF5 versioning and backward and forward compatibility issues, see the [API Compatibility Macros](https://docs.hdfgroup.org/hdf5/v1_14/v1_14_4/api-compat-macros.html) on the public website. + +## Participants: +- Product Manager — The individual responsible for the overall direction and development of a software product at The HDF Group. +- Release Manager — The individual responsible for coordinating and overseeing the activities specific to releasing a software product at The HDF Group. +- Software Developer — An individual or group responsible for performing maintenance on supported HDF software. +- Software Tester — An individual responsible for identifying, implementing, and conducting tests of software code, modules, packages, executables, and/or release binaries. +- Test Automation Team — A team at The HDF Group responsible for overseeing the daily automated regression tests of software maintained by the company's Sustaining Engineering program. + +## Tasks: +### 1. Plan Maintenance Release (Product Manager | Release Manager) + +### 2. Perform Software Maintenance (Software Developers | Product Manager | Release Manager) + +### 3. Prepare Release Notes (Release Manager) +1. Confirm that all non-trivial changes made to the source are reflected in the release notes. Verify the following: + - [HDF5 Milestones Projects](https://github.com/HDFGroup/hdf5/milestones) + - Each entry in [RELEASE.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/RELEASE.txt) traces to one or more resolved GH issues marked with FixVersion="X.Y.Z". + - Each resolved GH milestone issue traces to an entry in [RELEASE.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/RELEASE.txt). + - Each resolved GH milestone issue traces to one or more revisions to the HDF5 source. + - Each resolved GH milestone issue traces to one or more pull requests. +2. For each previously authored KNOWN ISSUE in the [RELEASE.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/RELEASE.txt), if the issue has been resolved or can no longer be confirmed, remove the issue from the [RELEASE.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/RELEASE.txt). + - Document any new known issues at the top of the list. +3. Update the TESTED CONFIGURATION FEATURES SUMMARY in [RELEASE.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/RELEASE.txt) to correspond to features and options that have been tested during the maintenance period by the automated daily regression tests. + - **See: Testing/Testing Systems(this is a page in confluence)** +4. Update current compiler information for each platform in the PLATFORMS TESTED section of [RELEASE.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/RELEASE.txt). +5. Review the [RELEASE.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/RELEASE.txt) for formatting and language to verify that it corresponds to guidelines found in **[Writing Notes in a RELEASE.txt(this is missing)]()** File. +6. Review and update, if needed, the [README](https://github.com/HDFGroup/hdf5/blob/develop/README.md) and [COPYING](https://github.com/HDFGroup/hdf5/blob/develop/COPYING) files. +7. Review and update all INSTALL_* files in [release_docs](https://github.com/HDFGroup/hdf5/tree/develop/release_docs), if needed. + - [INSTALL](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/INSTALL) should be general info and not require extensive changes + - [INSTALL_Auto.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/INSTALL_Auto.txt) are the instructions for building under autotools. + - [INSTALL_CMake.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/INSTALL_CMake.txt) are the instructions for building under CMake. + +### 4. Freeze Code (Release Manager | Test Automation Team) +1. Transition from performing maintenance on software to preparing for its delivery. +2. A few days before the code freeze, announce (via a product's developer mailing list and during team meetings) the pending freeze of the code for the release. On the day of the code freeze, send a "no more commits" message for the software being released and any third party software we develop that it depends on, as well as a "no more upgrades" message for other third party software the release depends on. + - Recently we haven’t announced a code freeze since it doesn’t take long to create the release branch and the support branch doesn’t need to remain frozen once the release branch is created. There are a few things that can be done on the support branch before the release branch is created, in particular updating the .so numbers. +3. Move all unresolved Milestone issues to the next release version in GitHub. +4. Verify that frozen code branch satisfies all existing regression test cases, and give the 'OK' to the release coordinator once all daily test configurations are passing as expected after the date of the code freeze. If there are failing tests after the code freeze date, coordinate with maintainers responsible for the failures to ensure that either the changes causing the failures are corrected or reverted. +5. Verify release branches for third-party software used: SZIP, ZLIB, and Plugins; and announce release versions to hdf5lib@lists.hdfgroup.org. + +### 5. Update Interface Version (Release Manager | Product Manager) +1. Verify interface additions, changes, and removals, and update the shared library interface version number. +2. Execute the CI snapshot workflow. + - Actions - “[hdf5 release build](https://github.com/HDFGroup/hdf5/blob/develop/.github/workflows/release.yml)” workflow and use the defaults. +3. Download and inspect release build source and binary files. Downloaded source files should build correctly, one or more binaries should install and run correctly. There should be nothing missing nor any extraneous files that aren’t meant for release. +4. Verify the interface compatibility reports between the current source and the previous release on the Github [Snapshots](https://github.com/HDFGroup/hdf5/releases/tag/snapshot-1.14) page. + - The compatibility reports are produced by the CI and are viewable in the Github [Releases/snapshot](https://github.com/HDFGroup/hdf5/releases/tag/snapshot) section. +5. Verify the interface compatibility reports between the current source and the previous release on the Github [Snapshots](https://github.com/HDFGroup/hdf5/releases/tag/snapshot-1.14) page. + - The compatibility reports are produced by the CI and are viewable in the Github [Releases/snapshot](https://github.com/HDFGroup/hdf5/releases/tag/snapshot) section. +6. Confirm the necessity of and approve of any interface-breaking changes. If any changes need to be reverted, task the developer who made the change to do so as soon as possible. If a change is reverted, return to the previous step and regenerate the compatibility report after the changes is made. Otherwise, continue to the next step. +7. Update the .so version numbers in the [config/lt_vers.am](https://github.com/HDFGroup/hdf5/blob/develop/config/lt_vers.am) file in the support branch according to [libtool's library interface version](https://www.gnu.org/software/libtool/manual/libtool.html#Versioning) scheme. + - See [Updating version info (Libtool)](https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info) for rules to help update library version numbers. +8. After the release branch has been created, run `./autogen.sh` to regenerate build system files on the release branch and commit the changes. + +### 6. Prepare Release Branch (Release Manager) +1. Get the release branch ready for pre-release testing and packaging. +2. For all release preparation operations, the release coordinator will clone and push directly to canonical HDF5: + - `$ git clone ​https://github.com/HDFGroup/hdf5.git` +3. Create a release preparation branch (hdf5_X_Y_Z) by branching off of the support branch (hdf5_X_Y): + - `$ git checkout hdf5_X_Y` + - `$ git checkout -b hdf5_X_Y_Z` + - or create the new branch in GitHub GUI. +4. Check that required CMake files point to the specific versions of the third-party software (szip, zlib and plugins) that they depend on. + - Update as needed. +5. Change the **support** branch to X.Y.{Z+1}-1 using the [bin/h5vers](https://github.com/HDFGroup/hdf5/blob/develop/bin/h5vers) script: + - `$ git checkout hdf5_X_Y` + - `$ bin/h5vers -s X.Y.{Z+1}-1;` + - `$ git commit -m "Updated support branch version number to X.Y.{Z+1}-1"` + - `$ git push` +6. Change the **release preparation branch**'s version number to X.Y.Z-{SR+1} using the [bin/h5vers](https://github.com/HDFGroup/hdf5/blob/develop/bin/h5vers) script: + - `$ git checkout hdf5_X_Y_Z;` + - `$ bin/h5vers -s X.Y.Z-{SR+1};` + - `$ git commit -m "Updated release preparation branch version number to X.Y.Z-{SR+1}"` + - `$ git push` +7. Update default configuration mode + - `$ git checkout hdf5_X_Y_Z;` and `$ bin/switch_maint_mode -disable ./configure.ac` to disable `AM_MAINTAINER_MODE`. + - Need to set option `HDF5_GENERATE_HEADERS` to `OFF`, currently in line 996 of [src/CMakeLists.txt](https://github.com/HDFGroup/hdf5/blob/develop/src/CMakeLists.txt). + - Change the **release preparation branch**'s (i.e. hdf5_X_Y_Z) default configuration mode from development to production in [configure.ac](https://github.com/HDFGroup/hdf5/blob/develop/configure.ac). + - Find “Determine build mode” in [configure.ac](https://github.com/HDFGroup/hdf5/blob/develop/configure.ac). + - Change `default=debug` to `default=production` at the bottom of the `AS_HELP_STRING` for `--enable-build-mode`. + - Under `if test "X-$BUILD_MODE" = X- ; then` change `BUILD_MODE=debug` to `BUILD_MODE=production`. + - Run `sh ./autogen.sh` to regenerate the UNIX build system files and commit the changes. (use `git status --ignored` to see the changes and `git add -f` to add all files. First delete any new files not to be committed, notably `src/H5public.h~` and `autom4te.cache/`.) + - `$ git push with commit message listing change steps for creating release branch` +8. E-mail hdf5lib@hdfgroup.org to indicate that the code freeze on the release support branch (i.e. hdf5_X_Y) has been lifted and development on the next maintenance release can resume. The code freeze will remain in place on the release preparation branch (i.e. hdf5_X_Y_Z) indefinitely. + +### 7. Perform Release Testing (Test Automation Team | Release Manager | Project Leads) +1. Verify that source and binary distributions of HDF5 are acceptable on all target operating environments. +2. Create a page on Confluence as a sub-page of the current release version's project collaboration page (see HDF5 Maintenance Releases) to document release testing results. +3. Document the test procedure that will be used for this release on the new sub-page. +4. Schedule daily stand-up meetings or other regular checkpoints to assure progress on testing tasks, and inform testing team of your expectations. +5. Schedule and enable daily automated regression testing of the release preparation branch (i.e. hdf5_X_Y_Z). Give the 'OK' to proceed once all required tests have verified that HDF5 is functioning as intended on all target operating environments. +6. Select release build from workflow. +7. Choose the release branch +8. Change ‘Release version tag’ name to 'hdf5_X.Y.Z.P' + - P is some pre-release number. +9. Send a message to the HDF forum indicating that a pre-release source package is available for testing at and that feedback from the user community on their test results is being accepted. +10. Contact paying clients who are interested in testing the pre-release source package and inform them that it is available for testing and that feedback on their test results of the pre-release is appreciated. +11. This should be automated and currently github binaries are not signed. + - Follow the [How to sign binaries with digital certificates(this is missing)]() work instructions to sign each Windows and Mac binary package with a digital certificate. +12. Once binaries are ready to be tested, send an e-mail notification or update the Confluence test dashboard page indicating source and binary test assignments and when results should be made available. +13. Use the pre-release source packages to build and test HDF5 on assigned platforms by hand. Build both shared and static libraries, Fortran, C++, and szip, and any additional configurations required on specific remote platforms based on customer support needs. +14. Use the pre-release binary packages found in /mnt/scr1/pre-release/hdf5/vXYZ/pre-\/binaries/{UNIX, Windows} to test according to the binary testing procedures for your assigned platforms. +15. Scripted Testing: + - UNIX: [Scripted Binary Testing of HDF5 on UNIX systems (this is missing)]() + - Windows: [Testing HDF5 Binaries(this is missing)]() +16. Manual Testing (i.e. verifying correct test outcomes via visual inspection): + - Use this if UNIX test script is not reporting correct results, yet binaries look OK. + - UNIX: [Manual Binary Testing of HDF5 on Unix systems (this is missing)]() +17. Update the test results Confluence page with status/outcome of all test assignments. +18. If any test source (hdf-forum, clients, internal testers, automated regression suite) identifies any issues: + - a) Enter the issue in JIRA summarizing the failure if it is not already there. + - b) Decide whether to resolve the issue for this release or simply document it as a known issue. + - c) Document and assign action items resulting from a) or b), and monitor them to closure. +19. Decide if another cycle of pre-release testing should occur based on the issue reports received and the actions taken during this cycle. If another round of testing is required (i.e. there were significant issues in pre-release testing which resulted in code changes), increment the subrelease version number and go back to step 7.2. If no further testing is required (i.e. no code changes were made and issues were documented as known issues, or code changes were trivial, unit tested, and exhaustive testing is unneeded), then proceed. + + +### 8. Finalize Release Notes (Release Manager) +1. Perform a final review of release notes and ensure that any new changes made to the source, any new known issues discovered, and any additional tests run since the code freeze have been reflected in RELEASE.txt and other appropriate in-source documentation files (INSTALL_*, etc.). (Refer to the sub-steps of step 3 for what to check). +2. Update the [RELEASE.txt](https://github.com/HDFGroup/hdf5/blob/develop/release_docs/RELEASE.txt) in the **support** branch (i.e. hdf5_X_Y) to remove entries in “Bugs fixed” and “New Features” sections and increment the version number for the following release (“Bug fixes since X.Y.Z” - occurs twice). + - `$ git checkout hdf5_X_Y` + - `$ vi RELEASE.txt # update RELEASE.txt to clear it out` + - `$ git commit -m "Reset RELEASE.txt in preparation for the next release."` + - `$ git push` +3. Update Release Notes in **release** branch (Release Manager) + +### 9. Package and Distribute Release (Release Manager) +1. h5vers will run autogen.sh, which can change the generated files if certain code files have been changed since the files generated by autogen.sh were committed on the release branch. This should be checked by running `git status --ignored;`, then running autogen.sh, then repeating `git status --ignored;`. If there are modified files from either git status command, they should be committed (or deleted if there are backup files or an autom4te.cache directory), and at least minimal testing should be done to see that the software is still good with the changes. +2. Set version for release, removing the subrelease string, initially `$ bin/h5vers -s X.Y.Z;`. Any subsequent patch releases will need the subrelease number. +3. Run `bin/release` (similar to 8.2) and commit all the changed files. +4. Select release build from workflow. + - Choose the release branch + - Change ‘Release version tag’ name to 'hdf5_X.Y.Z' + - Press "Run Workflow" +5. Review the release files in Github +6. Edit the Github Release and change status to Release + - Change status from Pre-release to Release + +### 10. Add the contents of the RELEASE.txt file in the release code to the HISTORY file in the **support** branch, just below the introductory lines at the top of the HISTORY file. + +### 11. Conduct Release Retrospective (Release Manager) +1. Schedule time and solicit comments from retrospective +2. Identify issues and document them diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a19126c8291..51464d53f5e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -610,6 +610,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 @@ -955,6 +964,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/H5CS.c b/src/H5CS.c index 0dca211604f..4172b0fe6bd 100644 --- a/src/H5CS.c +++ b/src/H5CS.c @@ -134,9 +134,11 @@ H5CS_print_stack(const H5CS_t *fstack, FILE *stream) if (!stream) stream = stderr; - fprintf(stream, "HDF5-DIAG: Function stack from %s ", H5_lib_vers_info_g); + 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()); +#ifdef H5_HAVE_THREADSAFE + fprintf(stream, " thread %" PRIu64 ".", H5TS_thread_id()); +#endif if (fstack && fstack->nused > 0) fprintf(stream, " Back trace follows."); fputc('\n', stream); diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index 4408774d5f0..208944e1053 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -16,9 +16,6 @@ * include H5Cprivate.h instead. */ -/* clang-format off */ -/* Maintain current format by disabling format for this file */ - #if !(defined H5C_FRIEND || defined H5C_MODULE) #error "Do not include this file outside the H5C package!" #endif @@ -30,23 +27,22 @@ #include "H5Cprivate.h" /* Other private headers needed by this file */ -#include "H5Clog.h" /* Cache logging */ -#include "H5SLprivate.h" /* Skip lists */ +#include "H5Clog.h" /* Cache logging */ +#include "H5SLprivate.h" /* Skip lists */ /**************************/ /* Package Private Macros */ /**************************/ /* Number of epoch markers active */ -#define H5C__MAX_EPOCH_MARKERS 10 +#define H5C__MAX_EPOCH_MARKERS 10 /* Cache configuration settings */ -#define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */ +#define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */ /* Initial allocated size of the "flush_dep_parent" array */ #define H5C_FLUSH_DEP_PARENT_INIT 8 - /**************************************************************************** * * We maintain doubly linked lists of instances of H5C_cache_entry_t for a @@ -70,148 +66,141 @@ #ifdef H5C_DO_SANITY_CHECKS -#define H5C__GEN_DLL_PRE_REMOVE_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ -do { if ((head_ptr) == NULL || (tail_ptr) == NULL || \ - (entry_ptr) == NULL || (len) <= 0 || \ - (list_size) < (entry_ptr)->size || \ - ((entry_ptr)->list_prev == NULL && (head_ptr) != (entry_ptr)) || \ - ((entry_ptr)->list_next == NULL && (tail_ptr) != (entry_ptr)) || \ - ((len) == 1 && \ - !((head_ptr) == (entry_ptr) && (tail_ptr) == (entry_ptr) && \ - (entry_ptr)->list_next == NULL && (entry_ptr)->list_prev == NULL && \ - (list_size) == (entry_ptr)->size \ - ) \ - ) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "DLL pre remove SC failed"); \ -} } while (0) - -#define H5C__GEN_DLL_PRE_INSERT_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ -if ((entry_ptr) == NULL || (entry_ptr)->list_next != NULL || (entry_ptr)->list_prev != NULL || \ - (((head_ptr) == NULL || (tail_ptr) == NULL) && (head_ptr) != (tail_ptr)) || \ - ((len) == 0 && \ - ((list_size) > 0 || (head_ptr) != NULL || (tail_ptr) != NULL) \ - ) || \ - ((len) == 1 && \ - ((head_ptr) != (tail_ptr) || (head_ptr) == NULL || \ - (head_ptr)->size != (list_size)) \ - ) || \ - ((len) >= 1 && \ - ((head_ptr) == NULL || (head_ptr)->list_prev != NULL || \ - (tail_ptr) == NULL || (tail_ptr)->list_next != NULL) \ - ) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "DLL pre insert SC failed"); \ -} - -#define H5C__GEN_DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) \ -if ((dll_len) <= 0 || (dll_size) <= 0 || (old_size) <= 0 || \ - (old_size) > (dll_size) || (new_size) <= 0 || \ - ((dll_len) == 1 && (old_size) != (dll_size)) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "DLL pre size update SC failed"); \ -} - -#define H5C__GEN_DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) \ -if ((new_size) > (dll_size) || ((dll_len) == 1 && (new_size) != (dll_size))) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "DLL post size update SC failed"); \ -} +#define H5C__GEN_DLL_PRE_REMOVE_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, \ + fail_val) \ + do { \ + if ((head_ptr) == NULL || (tail_ptr) == NULL || (entry_ptr) == NULL || (len) <= 0 || \ + (list_size) < (entry_ptr)->size || \ + ((entry_ptr)->list_prev == NULL && (head_ptr) != (entry_ptr)) || \ + ((entry_ptr)->list_next == NULL && (tail_ptr) != (entry_ptr)) || \ + ((len) == 1 && \ + !((head_ptr) == (entry_ptr) && (tail_ptr) == (entry_ptr) && (entry_ptr)->list_next == NULL && \ + (entry_ptr)->list_prev == NULL && (list_size) == (entry_ptr)->size))) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "DLL pre remove SC failed"); \ + } \ + } while (0) + +#define H5C__GEN_DLL_PRE_INSERT_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, \ + fail_val) \ + if ((entry_ptr) == NULL || (entry_ptr)->list_next != NULL || (entry_ptr)->list_prev != NULL || \ + (((head_ptr) == NULL || (tail_ptr) == NULL) && (head_ptr) != (tail_ptr)) || \ + ((len) == 0 && ((list_size) > 0 || (head_ptr) != NULL || (tail_ptr) != NULL)) || \ + ((len) == 1 && \ + ((head_ptr) != (tail_ptr) || (head_ptr) == NULL || (head_ptr)->size != (list_size))) || \ + ((len) >= 1 && ((head_ptr) == NULL || (head_ptr)->list_prev != NULL || (tail_ptr) == NULL || \ + (tail_ptr)->list_next != NULL))) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "DLL pre insert SC failed"); \ + } + +#define H5C__GEN_DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) \ + if ((dll_len) <= 0 || (dll_size) <= 0 || (old_size) <= 0 || (old_size) > (dll_size) || \ + (new_size) <= 0 || ((dll_len) == 1 && (old_size) != (dll_size))) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "DLL pre size update SC failed"); \ + } + +#define H5C__GEN_DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) \ + if ((new_size) > (dll_size) || ((dll_len) == 1 && (new_size) != (dll_size))) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "DLL post size update SC failed"); \ + } #else /* H5C_DO_SANITY_CHECKS */ -#define H5C__GEN_DLL_PRE_REMOVE_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) -#define H5C__GEN_DLL_PRE_INSERT_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) +#define H5C__GEN_DLL_PRE_REMOVE_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, \ + fail_val) +#define H5C__GEN_DLL_PRE_INSERT_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, \ + fail_val) #define H5C__GEN_DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) #define H5C__GEN_DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) #endif /* H5C_DO_SANITY_CHECKS */ -#define H5C__GEN_DLL_APPEND(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ -{ \ - H5C__GEN_DLL_PRE_INSERT_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ - if ((head_ptr) == NULL) { \ - (head_ptr) = (entry_ptr); \ - (tail_ptr) = (entry_ptr); \ - } \ - else { \ - (tail_ptr)->list_next = (entry_ptr); \ - (entry_ptr)->list_prev = (tail_ptr); \ - (tail_ptr) = (entry_ptr); \ - } \ - (len)++; \ - (list_size) += (entry_ptr)->size; \ -} /* H5C__GEN_DLL_APPEND() */ - -#define H5C__GEN_DLL_PREPEND(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ -{ \ - H5C__GEN_DLL_PRE_INSERT_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ - if ((head_ptr) == NULL) { \ - (head_ptr) = (entry_ptr); \ - (tail_ptr) = (entry_ptr); \ - } \ - else { \ - (head_ptr)->list_prev = (entry_ptr); \ - (entry_ptr)->list_next = (head_ptr); \ - (head_ptr) = (entry_ptr); \ - } \ - (len)++; \ - (list_size) += (entry_ptr)->size; \ -} /* H5C__GEN_DLL_PREPEND() */ - -#define H5C__GEN_DLL_REMOVE(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ -{ \ - H5C__GEN_DLL_PRE_REMOVE_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val); \ - if ((head_ptr) == (entry_ptr)) { \ - (head_ptr) = (entry_ptr)->list_next; \ - if ((head_ptr) != NULL) \ - (head_ptr)->list_prev = NULL; \ - } \ - else \ - (entry_ptr)->list_prev->list_next = (entry_ptr)->list_next; \ - if ((tail_ptr) == (entry_ptr)) { \ - (tail_ptr) = (entry_ptr)->list_prev; \ - if ((tail_ptr) != NULL) \ - (tail_ptr)->list_next = NULL; \ - } \ - else \ - (entry_ptr)->list_next->list_prev = (entry_ptr)->list_prev; \ - (entry_ptr)->list_next = NULL; \ - (entry_ptr)->list_prev = NULL; \ - (len)--; \ - (list_size) -= (entry_ptr)->size; \ -} /* H5C__GEN_DLL_REMOVE() */ - -#define H5C__GEN_DLL_UPDATE_FOR_SIZE_CHANGE(dll_len, dll_size, old_size, new_size, fail_val) \ -{ \ - H5C__GEN_DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) \ - (dll_size) -= (old_size); \ - (dll_size) += (new_size); \ - H5C__GEN_DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) \ -} /* H5C__GEN_DLL_UPDATE_FOR_SIZE_CHANGE() */ - +#define H5C__GEN_DLL_APPEND(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ + { \ + H5C__GEN_DLL_PRE_INSERT_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, \ + fail_val) \ + if ((head_ptr) == NULL) { \ + (head_ptr) = (entry_ptr); \ + (tail_ptr) = (entry_ptr); \ + } \ + else { \ + (tail_ptr)->list_next = (entry_ptr); \ + (entry_ptr)->list_prev = (tail_ptr); \ + (tail_ptr) = (entry_ptr); \ + } \ + (len)++; \ + (list_size) += (entry_ptr)->size; \ + } /* H5C__GEN_DLL_APPEND() */ + +#define H5C__GEN_DLL_PREPEND(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ + { \ + H5C__GEN_DLL_PRE_INSERT_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, \ + fail_val) \ + if ((head_ptr) == NULL) { \ + (head_ptr) = (entry_ptr); \ + (tail_ptr) = (entry_ptr); \ + } \ + else { \ + (head_ptr)->list_prev = (entry_ptr); \ + (entry_ptr)->list_next = (head_ptr); \ + (head_ptr) = (entry_ptr); \ + } \ + (len)++; \ + (list_size) += (entry_ptr)->size; \ + } /* H5C__GEN_DLL_PREPEND() */ + +#define H5C__GEN_DLL_REMOVE(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, fail_val) \ + { \ + H5C__GEN_DLL_PRE_REMOVE_SC(entry_ptr, list_next, list_prev, head_ptr, tail_ptr, len, list_size, \ + fail_val); \ + if ((head_ptr) == (entry_ptr)) { \ + (head_ptr) = (entry_ptr)->list_next; \ + if ((head_ptr) != NULL) \ + (head_ptr)->list_prev = NULL; \ + } \ + else \ + (entry_ptr)->list_prev->list_next = (entry_ptr)->list_next; \ + if ((tail_ptr) == (entry_ptr)) { \ + (tail_ptr) = (entry_ptr)->list_prev; \ + if ((tail_ptr) != NULL) \ + (tail_ptr)->list_next = NULL; \ + } \ + else \ + (entry_ptr)->list_next->list_prev = (entry_ptr)->list_prev; \ + (entry_ptr)->list_next = NULL; \ + (entry_ptr)->list_prev = NULL; \ + (len)--; \ + (list_size) -= (entry_ptr)->size; \ + } /* H5C__GEN_DLL_REMOVE() */ + +#define H5C__GEN_DLL_UPDATE_FOR_SIZE_CHANGE(dll_len, dll_size, old_size, new_size, fail_val) \ + { \ + H5C__GEN_DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) \ + (dll_size) -= (old_size); \ + (dll_size) += (new_size); \ + H5C__GEN_DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size, fail_val) \ + } /* H5C__GEN_DLL_UPDATE_FOR_SIZE_CHANGE() */ /* Macros that modify the LRU/protected/pinned lists */ -#define H5C__DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_APPEND(entry_ptr, next, prev, head_ptr, tail_ptr, len, list_size, fail_val) -#define H5C__DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_PREPEND(entry_ptr, next, prev, head_ptr, tail_ptr, len, list_size, fail_val) -#define H5C__DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_REMOVE(entry_ptr, next, prev, head_ptr, tail_ptr, len, list_size, fail_val) -#define H5C__DLL_UPDATE_FOR_SIZE_CHANGE(dll_len, dll_size, old_size, new_size, fail_val) \ +#define H5C__DLL_UPDATE_FOR_SIZE_CHANGE(dll_len, dll_size, old_size, new_size, fail_val) \ H5C__GEN_DLL_UPDATE_FOR_SIZE_CHANGE(dll_len, dll_size, old_size, new_size, fail_val) /* Macros that modify the "auxiliary" LRU list */ -#define H5C__AUX_DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__AUX_DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_APPEND(entry_ptr, aux_next, aux_prev, head_ptr, tail_ptr, len, list_size, fail_val) -#define H5C__AUX_DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__AUX_DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_PREPEND(entry_ptr, aux_next, aux_prev, head_ptr, tail_ptr, len, list_size, fail_val) -#define H5C__AUX_DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__AUX_DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_REMOVE(entry_ptr, aux_next, aux_prev, head_ptr, tail_ptr, len, list_size, fail_val) /* Macros that modify the "index" list */ -#define H5C__IL_DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__IL_DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_APPEND(entry_ptr, il_next, il_prev, head_ptr, tail_ptr, len, list_size, fail_val) -#define H5C__IL_DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__IL_DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_REMOVE(entry_ptr, il_next, il_prev, head_ptr, tail_ptr, len, list_size, fail_val) - /*********************************************************************** * * Stats collection macros @@ -225,336 +214,375 @@ if ((new_size) > (dll_size) || ((dll_len) == 1 && (new_size) != (dll_size))) { \ * ***********************************************************************/ -#define H5C__UPDATE_CACHE_HIT_RATE_STATS(cache_ptr, hit) \ -do { \ - (cache_ptr)->cache_accesses++; \ - if (hit) \ - (cache_ptr)->cache_hits++; \ -} while (0) +#define H5C__UPDATE_CACHE_HIT_RATE_STATS(cache_ptr, hit) \ + do { \ + (cache_ptr)->cache_accesses++; \ + if (hit) \ + (cache_ptr)->cache_hits++; \ + } while (0) #if H5C_COLLECT_CACHE_STATS -#define H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ -do { \ - if ((cache_ptr)->index_size > (cache_ptr)->max_index_size) \ - (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ - if ((cache_ptr)->clean_index_size > (cache_ptr)->max_clean_index_size) \ - (cache_ptr)->max_clean_index_size = (cache_ptr)->clean_index_size; \ - if ((cache_ptr)->dirty_index_size > (cache_ptr)->max_dirty_index_size) \ - (cache_ptr)->max_dirty_index_size = (cache_ptr)->dirty_index_size; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->dirty_pins[(entry_ptr)->type->id]++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_UNPROTECT(cache_ptr) \ -do { \ - if ((cache_ptr)->slist_len > (cache_ptr)->max_slist_len) \ - (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ - if ((cache_ptr)->slist_size > (cache_ptr)->max_slist_size) \ - (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ - if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, entry_ptr) \ -do { \ - if ((cache_ptr)->flush_in_progress) \ - (cache_ptr)->cache_flush_moves[(entry_ptr)->type->id]++; \ - if ((entry_ptr)->flush_in_progress) \ - (cache_ptr)->entry_flush_moves[(entry_ptr)->type->id]++; \ - (cache_ptr)->moves[(entry_ptr)->type->id]++; \ - (cache_ptr)->entries_relocated_counter++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) \ -do { \ - if ((cache_ptr)->flush_in_progress) \ - (cache_ptr)->cache_flush_size_changes[(entry_ptr)->type->id]++; \ - if ((entry_ptr)->flush_in_progress) \ - (cache_ptr)->entry_flush_size_changes[(entry_ptr)->type->id]++; \ - if ((entry_ptr)->size < (new_size)) { \ - (cache_ptr)->size_increases[(entry_ptr)->type->id]++; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr); \ - if ((cache_ptr)->slist_size > (cache_ptr)->max_slist_size) \ - (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ - if ((cache_ptr)->pl_size > (cache_ptr)->max_pl_size) \ - (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ - } else if ((entry_ptr)->size > (new_size)) { \ - (cache_ptr)->size_decreases[(entry_ptr)->type->id]++; \ - } \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) \ -do { \ - (cache_ptr)->total_ht_insertions++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) \ -do { \ - (cache_ptr)->total_ht_deletions++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, success, depth) \ -do { \ - if (success) { \ - (cache_ptr)->successful_ht_searches++; \ - (cache_ptr)->total_successful_ht_search_depth += depth; \ - } else { \ - (cache_ptr)->failed_ht_searches++; \ - (cache_ptr)->total_failed_ht_search_depth += depth; \ - } \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->unpins[(entry_ptr)->type->id]++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_PREFETCH(cache_ptr, dirty) \ -do { \ - (cache_ptr)->prefetches++; \ - if (dirty) \ - (cache_ptr)->dirty_prefetches++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_PREFETCH_HIT(cache_ptr) \ -do { \ - (cache_ptr)->prefetch_hits++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_SLIST_SCAN_RESTART(cache_ptr) \ -do { \ - (cache_ptr)->slist_scan_restarts++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_LRU_SCAN_RESTART(cache_ptr) \ -do { \ - (cache_ptr)->LRU_scan_restarts++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_INDEX_SCAN_RESTART(cache_ptr) \ -do { \ - (cache_ptr)->index_scan_restarts++; \ -} while (0) +#define H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + do { \ + if ((cache_ptr)->index_size > (cache_ptr)->max_index_size) \ + (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ + if ((cache_ptr)->clean_index_size > (cache_ptr)->max_clean_index_size) \ + (cache_ptr)->max_clean_index_size = (cache_ptr)->clean_index_size; \ + if ((cache_ptr)->dirty_index_size > (cache_ptr)->max_dirty_index_size) \ + (cache_ptr)->max_dirty_index_size = (cache_ptr)->dirty_index_size; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->dirty_pins[(entry_ptr)->type->id]++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_UNPROTECT(cache_ptr) \ + do { \ + if ((cache_ptr)->slist_len > (cache_ptr)->max_slist_len) \ + (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ + if ((cache_ptr)->slist_size > (cache_ptr)->max_slist_size) \ + (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ + if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, entry_ptr) \ + do { \ + if ((cache_ptr)->flush_in_progress) \ + (cache_ptr)->cache_flush_moves[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->flush_in_progress) \ + (cache_ptr)->entry_flush_moves[(entry_ptr)->type->id]++; \ + (cache_ptr)->moves[(entry_ptr)->type->id]++; \ + (cache_ptr)->entries_relocated_counter++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) \ + do { \ + if ((cache_ptr)->flush_in_progress) \ + (cache_ptr)->cache_flush_size_changes[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->flush_in_progress) \ + (cache_ptr)->entry_flush_size_changes[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->size < (new_size)) { \ + (cache_ptr)->size_increases[(entry_ptr)->type->id]++; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr); \ + if ((cache_ptr)->slist_size > (cache_ptr)->max_slist_size) \ + (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ + if ((cache_ptr)->pl_size > (cache_ptr)->max_pl_size) \ + (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ + } \ + else if ((entry_ptr)->size > (new_size)) { \ + (cache_ptr)->size_decreases[(entry_ptr)->type->id]++; \ + } \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) \ + do { \ + (cache_ptr)->total_ht_insertions++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) \ + do { \ + (cache_ptr)->total_ht_deletions++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, success, depth) \ + do { \ + if (success) { \ + (cache_ptr)->successful_ht_searches++; \ + (cache_ptr)->total_successful_ht_search_depth += depth; \ + } \ + else { \ + (cache_ptr)->failed_ht_searches++; \ + (cache_ptr)->total_failed_ht_search_depth += depth; \ + } \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->unpins[(entry_ptr)->type->id]++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_PREFETCH(cache_ptr, dirty) \ + do { \ + (cache_ptr)->prefetches++; \ + if (dirty) \ + (cache_ptr)->dirty_prefetches++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_PREFETCH_HIT(cache_ptr) \ + do { \ + (cache_ptr)->prefetch_hits++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_SLIST_SCAN_RESTART(cache_ptr) \ + do { \ + (cache_ptr)->slist_scan_restarts++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_LRU_SCAN_RESTART(cache_ptr) \ + do { \ + (cache_ptr)->LRU_scan_restarts++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_INDEX_SCAN_RESTART(cache_ptr) \ + do { \ + (cache_ptr)->index_scan_restarts++; \ + } while (0) #if H5C_COLLECT_CACHE_ENTRY_STATS -#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) \ -do { \ - (entry_ptr)->accesses = 0; \ - (entry_ptr)->clears = 0; \ - (entry_ptr)->flushes = 0; \ - (entry_ptr)->pins = 0; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->clears[(entry_ptr)->type->id]++; \ - if((entry_ptr)->is_pinned) \ - (cache_ptr)->pinned_clears[(entry_ptr)->type->id]++; \ - (entry_ptr)->clears++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->flushes[(entry_ptr)->type->id]++; \ - if((entry_ptr)->is_pinned) \ - (cache_ptr)->pinned_flushes[(entry_ptr)->type->id]++; \ - (entry_ptr)->flushes++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr, take_ownership) \ -do { \ - if (take_ownership) \ - (cache_ptr)->take_ownerships[(entry_ptr)->type->id]++; \ - else \ - (cache_ptr)->evictions[(entry_ptr)->type->id]++; \ - if ((entry_ptr)->accesses > (cache_ptr)->max_accesses[(entry_ptr)->type->id]) \ - (cache_ptr)->max_accesses[(entry_ptr)->type->id] = (entry_ptr)->accesses; \ - if ((entry_ptr)->accesses < (cache_ptr)->min_accesses[(entry_ptr)->type->id]) \ - (cache_ptr)->min_accesses[(entry_ptr)->type->id] = (entry_ptr)->accesses; \ - if ((entry_ptr)->clears > (cache_ptr)->max_clears[(entry_ptr)->type->id]) \ - (cache_ptr)->max_clears[(entry_ptr)->type->id] = (entry_ptr)->clears; \ - if ((entry_ptr)->flushes > (cache_ptr)->max_flushes[(entry_ptr)->type->id]) \ - (cache_ptr)->max_flushes[(entry_ptr)->type->id] = (entry_ptr)->flushes; \ - if ((entry_ptr)->size > (cache_ptr)->max_size[(entry_ptr)->type->id]) \ - (cache_ptr)->max_size[(entry_ptr)->type->id] = (entry_ptr)->size; \ - if ((entry_ptr)->pins > (cache_ptr)->max_pins[(entry_ptr)->type->id]) \ - (cache_ptr)->max_pins[(entry_ptr)->type->id] = (entry_ptr)->pins; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->insertions[(entry_ptr)->type->id]++; \ - if ((entry_ptr)->is_pinned) { \ - (cache_ptr)->pinned_insertions[(entry_ptr)->type->id]++; \ - (cache_ptr)->pins[(entry_ptr)->type->id]++; \ - (entry_ptr)->pins++; \ - if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ - } \ - if ((cache_ptr)->index_len > (cache_ptr)->max_index_len) \ - (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr); \ - if ((cache_ptr)->slist_len > (cache_ptr)->max_slist_len) \ - (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ - if ((cache_ptr)->slist_size > (cache_ptr)->max_slist_size) \ - (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ - if ((entry_ptr)->size > (cache_ptr)->max_size[(entry_ptr)->type->id]) \ - (cache_ptr)->max_size[(entry_ptr)->type->id] = (entry_ptr)->size; \ - (cache_ptr)->entries_inserted_counter++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) \ -do { \ - if (hit) \ - (cache_ptr)->hits[(entry_ptr)->type->id]++; \ - else \ - (cache_ptr)->misses[(entry_ptr)->type->id]++; \ - if (!(entry_ptr)->is_read_only) \ - (cache_ptr)->write_protects[(entry_ptr)->type->id]++; \ - else { \ - (cache_ptr)->read_protects[(entry_ptr)->type->id]++; \ - if ((entry_ptr)->ro_ref_count > (cache_ptr)->max_read_protects[(entry_ptr)->type->id]) \ - (cache_ptr)->max_read_protects[(entry_ptr)->type->id] = (entry_ptr)->ro_ref_count; \ - } \ - if ((cache_ptr)->index_len > (cache_ptr)->max_index_len) \ - (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr); \ - if ((cache_ptr)->pl_len > (cache_ptr)->max_pl_len) \ - (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ - if ((cache_ptr)->pl_size > (cache_ptr)->max_pl_size) \ - (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ - if ((entry_ptr)->size > (cache_ptr)->max_size[(entry_ptr)->type->id]) \ - (cache_ptr)->max_size[(entry_ptr)->type->id] = (entry_ptr)->size; \ - (entry_ptr)->accesses++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->pins[(entry_ptr)->type->id]++; \ - (entry_ptr)->pins++; \ - if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ -} while (0) +#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) \ + do { \ + (entry_ptr)->accesses = 0; \ + (entry_ptr)->clears = 0; \ + (entry_ptr)->flushes = 0; \ + (entry_ptr)->pins = 0; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->clears[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->is_pinned) \ + (cache_ptr)->pinned_clears[(entry_ptr)->type->id]++; \ + (entry_ptr)->clears++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->flushes[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->is_pinned) \ + (cache_ptr)->pinned_flushes[(entry_ptr)->type->id]++; \ + (entry_ptr)->flushes++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr, take_ownership) \ + do { \ + if (take_ownership) \ + (cache_ptr)->take_ownerships[(entry_ptr)->type->id]++; \ + else \ + (cache_ptr)->evictions[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->accesses > (cache_ptr)->max_accesses[(entry_ptr)->type->id]) \ + (cache_ptr)->max_accesses[(entry_ptr)->type->id] = (entry_ptr)->accesses; \ + if ((entry_ptr)->accesses < (cache_ptr)->min_accesses[(entry_ptr)->type->id]) \ + (cache_ptr)->min_accesses[(entry_ptr)->type->id] = (entry_ptr)->accesses; \ + if ((entry_ptr)->clears > (cache_ptr)->max_clears[(entry_ptr)->type->id]) \ + (cache_ptr)->max_clears[(entry_ptr)->type->id] = (entry_ptr)->clears; \ + if ((entry_ptr)->flushes > (cache_ptr)->max_flushes[(entry_ptr)->type->id]) \ + (cache_ptr)->max_flushes[(entry_ptr)->type->id] = (entry_ptr)->flushes; \ + if ((entry_ptr)->size > (cache_ptr)->max_size[(entry_ptr)->type->id]) \ + (cache_ptr)->max_size[(entry_ptr)->type->id] = (entry_ptr)->size; \ + if ((entry_ptr)->pins > (cache_ptr)->max_pins[(entry_ptr)->type->id]) \ + (cache_ptr)->max_pins[(entry_ptr)->type->id] = (entry_ptr)->pins; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->insertions[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->is_pinned) { \ + (cache_ptr)->pinned_insertions[(entry_ptr)->type->id]++; \ + (cache_ptr)->pins[(entry_ptr)->type->id]++; \ + (entry_ptr)->pins++; \ + if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ + } \ + if ((cache_ptr)->index_len > (cache_ptr)->max_index_len) \ + (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr); \ + if ((cache_ptr)->slist_len > (cache_ptr)->max_slist_len) \ + (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ + if ((cache_ptr)->slist_size > (cache_ptr)->max_slist_size) \ + (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ + if ((entry_ptr)->size > (cache_ptr)->max_size[(entry_ptr)->type->id]) \ + (cache_ptr)->max_size[(entry_ptr)->type->id] = (entry_ptr)->size; \ + (cache_ptr)->entries_inserted_counter++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) \ + do { \ + if (hit) \ + (cache_ptr)->hits[(entry_ptr)->type->id]++; \ + else \ + (cache_ptr)->misses[(entry_ptr)->type->id]++; \ + if (!(entry_ptr)->is_read_only) \ + (cache_ptr)->write_protects[(entry_ptr)->type->id]++; \ + else { \ + (cache_ptr)->read_protects[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->ro_ref_count > (cache_ptr)->max_read_protects[(entry_ptr)->type->id]) \ + (cache_ptr)->max_read_protects[(entry_ptr)->type->id] = (entry_ptr)->ro_ref_count; \ + } \ + if ((cache_ptr)->index_len > (cache_ptr)->max_index_len) \ + (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr); \ + if ((cache_ptr)->pl_len > (cache_ptr)->max_pl_len) \ + (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ + if ((cache_ptr)->pl_size > (cache_ptr)->max_pl_size) \ + (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ + if ((entry_ptr)->size > (cache_ptr)->max_size[(entry_ptr)->type->id]) \ + (cache_ptr)->max_size[(entry_ptr)->type->id] = (entry_ptr)->size; \ + (entry_ptr)->accesses++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->pins[(entry_ptr)->type->id]++; \ + (entry_ptr)->pins++; \ + if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ + } while (0) #else /* H5C_COLLECT_CACHE_ENTRY_STATS */ #define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) -#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->clears[(entry_ptr)->type->id]++; \ - if((entry_ptr)->is_pinned) \ - (cache_ptr)->pinned_clears[(entry_ptr)->type->id]++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->flushes[(entry_ptr)->type->id]++; \ - if ((entry_ptr)->is_pinned) \ - (cache_ptr)->pinned_flushes[(entry_ptr)->type->id]++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr, take_ownership) \ -do { \ - if (take_ownership) \ - (cache_ptr)->take_ownerships[(entry_ptr)->type->id]++; \ - else \ - (cache_ptr)->evictions[(entry_ptr)->type->id]++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->insertions[(entry_ptr)->type->id]++; \ - if ((entry_ptr)->is_pinned) { \ - (cache_ptr)->pinned_insertions[(entry_ptr)->type->id]++; \ - (cache_ptr)->pins[(entry_ptr)->type->id]++; \ - if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ - } \ - if ((cache_ptr)->index_len > (cache_ptr)->max_index_len) \ - (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ - if ((cache_ptr)->slist_len > (cache_ptr)->max_slist_len) \ - (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ - if ((cache_ptr)->slist_size > (cache_ptr)->max_slist_size) \ - (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ - (cache_ptr)->entries_inserted_counter++; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) \ -do { \ - if (hit) \ - (cache_ptr)->hits[(entry_ptr)->type->id]++; \ - else \ - (cache_ptr)->misses[(entry_ptr)->type->id]++; \ - if (!(entry_ptr)->is_read_only) \ - (cache_ptr)->write_protects[(entry_ptr)->type->id]++; \ - else { \ - (cache_ptr)->read_protects[(entry_ptr)->type->id]++; \ - if ((entry_ptr)->ro_ref_count > \ - (cache_ptr)->max_read_protects[(entry_ptr)->type->id]) \ - (cache_ptr)->max_read_protects[(entry_ptr)->type->id] = \ - (entry_ptr)->ro_ref_count; \ - } \ - if ((cache_ptr)->index_len > (cache_ptr)->max_index_len) \ - (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ - if ((cache_ptr)->pl_len > (cache_ptr)->max_pl_len) \ - (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ - if ((cache_ptr)->pl_size > (cache_ptr)->max_pl_size) \ - (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ -} while (0) - -#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->pins[(entry_ptr)->type->id]++; \ - if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ -} while (0) +#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->clears[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->is_pinned) \ + (cache_ptr)->pinned_clears[(entry_ptr)->type->id]++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->flushes[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->is_pinned) \ + (cache_ptr)->pinned_flushes[(entry_ptr)->type->id]++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr, take_ownership) \ + do { \ + if (take_ownership) \ + (cache_ptr)->take_ownerships[(entry_ptr)->type->id]++; \ + else \ + (cache_ptr)->evictions[(entry_ptr)->type->id]++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->insertions[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->is_pinned) { \ + (cache_ptr)->pinned_insertions[(entry_ptr)->type->id]++; \ + (cache_ptr)->pins[(entry_ptr)->type->id]++; \ + if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ + } \ + if ((cache_ptr)->index_len > (cache_ptr)->max_index_len) \ + (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + if ((cache_ptr)->slist_len > (cache_ptr)->max_slist_len) \ + (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ + if ((cache_ptr)->slist_size > (cache_ptr)->max_slist_size) \ + (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ + (cache_ptr)->entries_inserted_counter++; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) \ + do { \ + if (hit) \ + (cache_ptr)->hits[(entry_ptr)->type->id]++; \ + else \ + (cache_ptr)->misses[(entry_ptr)->type->id]++; \ + if (!(entry_ptr)->is_read_only) \ + (cache_ptr)->write_protects[(entry_ptr)->type->id]++; \ + else { \ + (cache_ptr)->read_protects[(entry_ptr)->type->id]++; \ + if ((entry_ptr)->ro_ref_count > (cache_ptr)->max_read_protects[(entry_ptr)->type->id]) \ + (cache_ptr)->max_read_protects[(entry_ptr)->type->id] = (entry_ptr)->ro_ref_count; \ + } \ + if ((cache_ptr)->index_len > (cache_ptr)->max_index_len) \ + (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + if ((cache_ptr)->pl_len > (cache_ptr)->max_pl_len) \ + (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ + if ((cache_ptr)->pl_size > (cache_ptr)->max_pl_size) \ + (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ + } while (0) + +#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->pins[(entry_ptr)->type->id]++; \ + if ((cache_ptr)->pel_len > (cache_ptr)->max_pel_len) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ((cache_ptr)->pel_size > (cache_ptr)->max_pel_size) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ + } while (0) #endif /* H5C_COLLECT_CACHE_ENTRY_STATS */ #else /* H5C_COLLECT_CACHE_STATS */ -#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_UNPROTECT(cache_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, entry_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) do {} while(0) -#define H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, success, depth) do {} while(0) -#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr, take_ownership) do {} while(0) -#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) do {} while(0) -#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_PREFETCH(cache_ptr, dirty) do {} while(0) -#define H5C__UPDATE_STATS_FOR_PREFETCH_HIT(cache_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_SLIST_SCAN_RESTART(cache_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_LRU_SCAN_RESTART(cache_ptr) do {} while(0) -#define H5C__UPDATE_STATS_FOR_INDEX_SCAN_RESTART(cache_ptr) do {} while(0) +#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_UNPROTECT(cache_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, entry_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, success, depth) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr, take_ownership) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_PREFETCH(cache_ptr, dirty) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_PREFETCH_HIT(cache_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_SLIST_SCAN_RESTART(cache_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_LRU_SCAN_RESTART(cache_ptr) \ + do { \ + } while (0) +#define H5C__UPDATE_STATS_FOR_INDEX_SCAN_RESTART(cache_ptr) \ + do { \ + } while (0) #endif /* H5C_COLLECT_CACHE_STATS */ - /*********************************************************************** * * Hash table access and manipulation macros: @@ -564,263 +592,210 @@ do { \ * ***********************************************************************/ -#define H5C__HASH_MASK ((size_t)(H5C__HASH_TABLE_LEN - 1) << 3) -#define H5C__HASH_FCN(x) (int)((unsigned)((x) & H5C__HASH_MASK) >> 3) - -#define H5C__POST_HT_SHIFT_TO_FRONT_SC_CMP(cache_ptr, entry_ptr, k) \ -((cache_ptr) == NULL || (cache_ptr)->index[k] != (entry_ptr) || \ - (entry_ptr)->ht_prev != NULL \ -) -#define H5C__PRE_HT_SEARCH_SC_CMP(cache_ptr, entry_addr) \ -((cache_ptr) == NULL || \ - (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - !H5_addr_defined(entry_addr) || \ - H5C__HASH_FCN(entry_addr) < 0 || \ - H5C__HASH_FCN(entry_addr) >= H5C__HASH_TABLE_LEN \ -) -#define H5C__POST_SUC_HT_SEARCH_SC_CMP(cache_ptr, entry_ptr, k) \ -((cache_ptr) == NULL || (cache_ptr)->index_len < 1 || \ - (entry_ptr) == NULL || \ - (cache_ptr)->index_size < (entry_ptr)->size || \ - (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (entry_ptr)->size <= 0 || \ - (cache_ptr)->index[k] == NULL || \ - ((cache_ptr)->index[k] != (entry_ptr) && (entry_ptr)->ht_prev == NULL) || \ - ((cache_ptr)->index[k] == (entry_ptr) && (entry_ptr)->ht_prev != NULL) || \ - ((entry_ptr)->ht_prev != NULL && (entry_ptr)->ht_prev->ht_next != (entry_ptr)) || \ - ((entry_ptr)->ht_next != NULL && (entry_ptr)->ht_next->ht_prev != (entry_ptr)) \ -) +#define H5C__HASH_MASK ((size_t)(H5C__HASH_TABLE_LEN - 1) << 3) +#define H5C__HASH_FCN(x) (int)((unsigned)((x)&H5C__HASH_MASK) >> 3) + +#define H5C__POST_HT_SHIFT_TO_FRONT_SC_CMP(cache_ptr, entry_ptr, k) \ + ((cache_ptr) == NULL || (cache_ptr)->index[k] != (entry_ptr) || (entry_ptr)->ht_prev != NULL) +#define H5C__PRE_HT_SEARCH_SC_CMP(cache_ptr, entry_addr) \ + ((cache_ptr) == NULL || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + !H5_addr_defined(entry_addr) || H5C__HASH_FCN(entry_addr) < 0 || \ + H5C__HASH_FCN(entry_addr) >= H5C__HASH_TABLE_LEN) +#define H5C__POST_SUC_HT_SEARCH_SC_CMP(cache_ptr, entry_ptr, k) \ + ((cache_ptr) == NULL || (cache_ptr)->index_len < 1 || (entry_ptr) == NULL || \ + (cache_ptr)->index_size < (entry_ptr)->size || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (entry_ptr)->size <= 0 || (cache_ptr)->index[k] == NULL || \ + ((cache_ptr)->index[k] != (entry_ptr) && (entry_ptr)->ht_prev == NULL) || \ + ((cache_ptr)->index[k] == (entry_ptr) && (entry_ptr)->ht_prev != NULL) || \ + ((entry_ptr)->ht_prev != NULL && (entry_ptr)->ht_prev->ht_next != (entry_ptr)) || \ + ((entry_ptr)->ht_next != NULL && (entry_ptr)->ht_next->ht_prev != (entry_ptr))) #ifdef H5C_DO_SANITY_CHECKS -#define H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ -if ((cache_ptr) == NULL || \ - (entry_ptr) == NULL || !H5_addr_defined((entry_ptr)->addr) || \ - (entry_ptr)->ht_next != NULL || (entry_ptr)->ht_prev != NULL || \ - (entry_ptr)->size <= 0 || \ - H5C__HASH_FCN((entry_ptr)->addr) < 0 || \ - H5C__HASH_FCN((entry_ptr)->addr) >= H5C__HASH_TABLE_LEN || \ - (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ - (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ - (entry_ptr)->ring <= H5C_RING_UNDEFINED || \ - (entry_ptr)->ring >= H5C_RING_NTYPES || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ - (cache_ptr)->index_len != (cache_ptr)->il_len || \ - (cache_ptr)->index_size != (cache_ptr)->il_size \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, "pre HT insert SC failed"); \ -} - -#define H5C__POST_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ -if ((cache_ptr) == NULL || \ - (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ - (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] == 0 || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ - (cache_ptr)->index_len != (cache_ptr)->il_len || \ - (cache_ptr)->index_size != (cache_ptr)->il_size \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, "post HT insert SC failed"); \ -} - -#define H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr, fail_val) \ -if ( (cache_ptr) == NULL || (cache_ptr)->index_len < 1 || \ - (entry_ptr) == NULL || \ - (cache_ptr)->index_size < (entry_ptr)->size || \ - !H5_addr_defined((entry_ptr)->addr) || \ - (entry_ptr)->size <= 0 || \ - H5C__HASH_FCN((entry_ptr)->addr) < 0 || \ - H5C__HASH_FCN((entry_ptr)->addr) >= H5C__HASH_TABLE_LEN || \ - (cache_ptr)->index[H5C__HASH_FCN((entry_ptr)->addr)] == NULL || \ - ((cache_ptr)->index[H5C__HASH_FCN((entry_ptr)->addr)] != (entry_ptr) && \ - (entry_ptr)->ht_prev == NULL) || \ - ((cache_ptr)->index[H5C__HASH_FCN((entry_ptr)->addr)] == (entry_ptr) && \ - (entry_ptr)->ht_prev != NULL) || \ - (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ - (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ - (entry_ptr)->ring <= H5C_RING_UNDEFINED || \ - (entry_ptr)->ring >= H5C_RING_NTYPES || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] <= 0 || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] < (entry_ptr)->size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ - (cache_ptr)->index_len != (cache_ptr)->il_len || \ - (cache_ptr)->index_size != (cache_ptr)->il_size \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT remove SC failed"); \ -} - -#define H5C__POST_HT_REMOVE_SC(cache_ptr, entry_ptr, fail_val) \ -if ((cache_ptr) == NULL || \ - (entry_ptr) == NULL || !H5_addr_defined((entry_ptr)->addr) || \ - (entry_ptr)->size <= 0 || \ - (entry_ptr)->ht_next != NULL || \ - (entry_ptr)->ht_prev != NULL || \ - (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ - (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ - (cache_ptr)->index_len != (cache_ptr)->il_len || \ - (cache_ptr)->index_size != (cache_ptr)->il_size \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT remove SC failed"); \ -} - -#define H5C__PRE_HT_SEARCH_SC(cache_ptr, entry_addr, fail_val) \ -if (H5C__PRE_HT_SEARCH_SC_CMP(cache_ptr, entry_addr)) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT search SC failed"); \ -} - -#define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, k, fail_val) \ -if(H5C__POST_SUC_HT_SEARCH_SC_CMP(cache_ptr, entry_ptr, k)) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post successful HT search SC failed"); \ -} - -#define H5C__POST_HT_SHIFT_TO_FRONT_SC(cache_ptr, entry_ptr, k, fail_val) \ -if(H5C__POST_HT_SHIFT_TO_FRONT_SC_CMP(cache_ptr, entry_ptr, k)) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT shift to front SC failed"); \ -} - -#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ - entry_ptr, was_clean, fail_val) \ -if ((cache_ptr) == NULL || \ - (cache_ptr)->index_len <= 0 || (cache_ptr)->index_size <= 0 || \ - (new_size) <= 0 || (old_size) > (cache_ptr)->index_size || \ - ((cache_ptr)->index_len == 1 && (cache_ptr)->index_size != (old_size)) || \ - (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ - (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ - ((!(was_clean) || (cache_ptr)->clean_index_size < (old_size)) && \ - ((was_clean) || (cache_ptr)->dirty_index_size < (old_size))) || \ - (entry_ptr) == NULL || \ - (entry_ptr)->ring <= H5C_RING_UNDEFINED || \ - (entry_ptr)->ring >= H5C_RING_NTYPES || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] <= 0 || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ - (cache_ptr)->index_len != (cache_ptr)->il_len || \ - (cache_ptr)->index_size != (cache_ptr)->il_size \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT entry size change SC failed"); \ -} - -#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ - entry_ptr, fail_val) \ -if ((cache_ptr) == NULL || \ - (cache_ptr)->index_len <= 0 || (cache_ptr)->index_size <= 0 || \ - (new_size) > (cache_ptr)->index_size || \ - (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ - (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ - ((!((entry_ptr)->is_dirty ) || (cache_ptr)->dirty_index_size < (new_size)) && \ - ((entry_ptr)->is_dirty || (cache_ptr)->clean_index_size < (new_size)) \ - ) || \ - ((cache_ptr)->index_len == 1 && (cache_ptr)->index_size != (new_size)) || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ - (cache_ptr)->index_len != (cache_ptr)->il_len || \ - (cache_ptr)->index_size != (cache_ptr)->il_size \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT entry size change SC failed"); \ -} - -#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr, fail_val) \ -if ((cache_ptr) == NULL || (cache_ptr)->index_len <= 0 || \ - (entry_ptr) == NULL || (entry_ptr)->is_dirty != false || \ - (cache_ptr)->index_size < (entry_ptr)->size || \ - (cache_ptr)->dirty_index_size < (entry_ptr)->size || \ - (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < ((cache_ptr)->clean_index_size) || \ - (cache_ptr)->index_size < ((cache_ptr)->dirty_index_size) || \ - (entry_ptr)->ring <= H5C_RING_UNDEFINED || \ - (entry_ptr)->ring >= H5C_RING_NTYPES || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] <= 0 || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT update for entry clean SC failed"); \ -} - -#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr, fail_val) \ -if ((cache_ptr) == NULL || (cache_ptr)->index_len <= 0 || \ - (entry_ptr) == NULL || (entry_ptr)->is_dirty != true || \ - (cache_ptr)->index_size < (entry_ptr)->size || \ - (cache_ptr)->clean_index_size < (entry_ptr)->size || \ - (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ - (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ - (entry_ptr)->ring <= H5C_RING_UNDEFINED || \ - (entry_ptr)->ring >= H5C_RING_NTYPES || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] <= 0 || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT update for entry dirty SC failed"); \ -} - -#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr, fail_val) \ -if ((cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ - (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT update for entry clean SC failed"); \ -} - -#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr, fail_val) \ -if ((cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ - (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ - (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ - ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT update for entry dirty SC failed"); \ -} +#define H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ + if ((cache_ptr) == NULL || (entry_ptr) == NULL || !H5_addr_defined((entry_ptr)->addr) || \ + (entry_ptr)->ht_next != NULL || (entry_ptr)->ht_prev != NULL || (entry_ptr)->size <= 0 || \ + H5C__HASH_FCN((entry_ptr)->addr) < 0 || H5C__HASH_FCN((entry_ptr)->addr) >= H5C__HASH_TABLE_LEN || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ + (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ + (entry_ptr)->ring <= H5C_RING_UNDEFINED || (entry_ptr)->ring >= H5C_RING_NTYPES || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ + (cache_ptr)->index_len != (cache_ptr)->il_len || (cache_ptr)->index_size != (cache_ptr)->il_size) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, "pre HT insert SC failed"); \ + } + +#define H5C__POST_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ + if ((cache_ptr) == NULL || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ + (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] == 0 || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ + (cache_ptr)->index_len != (cache_ptr)->il_len || (cache_ptr)->index_size != (cache_ptr)->il_size) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, "post HT insert SC failed"); \ + } + +#define H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr, fail_val) \ + if ((cache_ptr) == NULL || (cache_ptr)->index_len < 1 || (entry_ptr) == NULL || \ + (cache_ptr)->index_size < (entry_ptr)->size || !H5_addr_defined((entry_ptr)->addr) || \ + (entry_ptr)->size <= 0 || H5C__HASH_FCN((entry_ptr)->addr) < 0 || \ + H5C__HASH_FCN((entry_ptr)->addr) >= H5C__HASH_TABLE_LEN || \ + (cache_ptr)->index[H5C__HASH_FCN((entry_ptr)->addr)] == NULL || \ + ((cache_ptr)->index[H5C__HASH_FCN((entry_ptr)->addr)] != (entry_ptr) && \ + (entry_ptr)->ht_prev == NULL) || \ + ((cache_ptr)->index[H5C__HASH_FCN((entry_ptr)->addr)] == (entry_ptr) && \ + (entry_ptr)->ht_prev != NULL) || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ + (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ + (entry_ptr)->ring <= H5C_RING_UNDEFINED || (entry_ptr)->ring >= H5C_RING_NTYPES || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] <= 0 || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] < (entry_ptr)->size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ + (cache_ptr)->index_len != (cache_ptr)->il_len || (cache_ptr)->index_size != (cache_ptr)->il_size) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT remove SC failed"); \ + } + +#define H5C__POST_HT_REMOVE_SC(cache_ptr, entry_ptr, fail_val) \ + if ((cache_ptr) == NULL || (entry_ptr) == NULL || !H5_addr_defined((entry_ptr)->addr) || \ + (entry_ptr)->size <= 0 || (entry_ptr)->ht_next != NULL || (entry_ptr)->ht_prev != NULL || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ + (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ + (cache_ptr)->index_len != (cache_ptr)->il_len || (cache_ptr)->index_size != (cache_ptr)->il_size) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT remove SC failed"); \ + } + +#define H5C__PRE_HT_SEARCH_SC(cache_ptr, entry_addr, fail_val) \ + if (H5C__PRE_HT_SEARCH_SC_CMP(cache_ptr, entry_addr)) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT search SC failed"); \ + } + +#define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, k, fail_val) \ + if (H5C__POST_SUC_HT_SEARCH_SC_CMP(cache_ptr, entry_ptr, k)) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post successful HT search SC failed"); \ + } + +#define H5C__POST_HT_SHIFT_TO_FRONT_SC(cache_ptr, entry_ptr, k, fail_val) \ + if (H5C__POST_HT_SHIFT_TO_FRONT_SC_CMP(cache_ptr, entry_ptr, k)) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT shift to front SC failed"); \ + } + +#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, entry_ptr, was_clean, fail_val) \ + if ((cache_ptr) == NULL || (cache_ptr)->index_len <= 0 || (cache_ptr)->index_size <= 0 || \ + (new_size) <= 0 || (old_size) > (cache_ptr)->index_size || \ + ((cache_ptr)->index_len == 1 && (cache_ptr)->index_size != (old_size)) || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ + (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ + ((!(was_clean) || (cache_ptr)->clean_index_size < (old_size)) && \ + ((was_clean) || (cache_ptr)->dirty_index_size < (old_size))) || \ + (entry_ptr) == NULL || (entry_ptr)->ring <= H5C_RING_UNDEFINED || \ + (entry_ptr)->ring >= H5C_RING_NTYPES || (cache_ptr)->index_ring_len[(entry_ptr)->ring] <= 0 || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ + (cache_ptr)->index_len != (cache_ptr)->il_len || (cache_ptr)->index_size != (cache_ptr)->il_size) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT entry size change SC failed"); \ + } + +#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, entry_ptr, fail_val) \ + if ((cache_ptr) == NULL || (cache_ptr)->index_len <= 0 || (cache_ptr)->index_size <= 0 || \ + (new_size) > (cache_ptr)->index_size || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ + (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ + ((!((entry_ptr)->is_dirty) || (cache_ptr)->dirty_index_size < (new_size)) && \ + ((entry_ptr)->is_dirty || (cache_ptr)->clean_index_size < (new_size))) || \ + ((cache_ptr)->index_len == 1 && (cache_ptr)->index_size != (new_size)) || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) || \ + (cache_ptr)->index_len != (cache_ptr)->il_len || (cache_ptr)->index_size != (cache_ptr)->il_size) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT entry size change SC failed"); \ + } + +#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr, fail_val) \ + if ((cache_ptr) == NULL || (cache_ptr)->index_len <= 0 || (entry_ptr) == NULL || \ + (entry_ptr)->is_dirty != false || (cache_ptr)->index_size < (entry_ptr)->size || \ + (cache_ptr)->dirty_index_size < (entry_ptr)->size || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < ((cache_ptr)->clean_index_size) || \ + (cache_ptr)->index_size < ((cache_ptr)->dirty_index_size) || \ + (entry_ptr)->ring <= H5C_RING_UNDEFINED || (entry_ptr)->ring >= H5C_RING_NTYPES || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] <= 0 || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring])) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT update for entry clean SC failed"); \ + } + +#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr, fail_val) \ + if ((cache_ptr) == NULL || (cache_ptr)->index_len <= 0 || (entry_ptr) == NULL || \ + (entry_ptr)->is_dirty != true || (cache_ptr)->index_size < (entry_ptr)->size || \ + (cache_ptr)->clean_index_size < (entry_ptr)->size || \ + (cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ + (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ + (entry_ptr)->ring <= H5C_RING_UNDEFINED || (entry_ptr)->ring >= H5C_RING_NTYPES || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] <= 0 || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring])) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "pre HT update for entry dirty SC failed"); \ + } + +#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr, fail_val) \ + if ((cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ + (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring])) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT update for entry clean SC failed"); \ + } + +#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr, fail_val) \ + if ((cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) || \ + (cache_ptr)->index_size < (cache_ptr)->clean_index_size || \ + (cache_ptr)->index_size < (cache_ptr)->dirty_index_size || \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring] > (cache_ptr)->index_len || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] > (cache_ptr)->index_size || \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] != \ + ((cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] + \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring])) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fail_val), "post HT update for entry dirty SC failed"); \ + } #else /* H5C_DO_SANITY_CHECKS */ @@ -840,153 +815,149 @@ if ((cache_ptr)->index_size != ((cache_ptr)->clean_index_size + (cache_ptr)->dir #endif /* H5C_DO_SANITY_CHECKS */ - -#define H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, fail_val) \ -do { \ - int k; \ - H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ - k = H5C__HASH_FCN((entry_ptr)->addr); \ - if((cache_ptr)->index[k] != NULL) { \ - (entry_ptr)->ht_next = (cache_ptr)->index[k]; \ - (entry_ptr)->ht_next->ht_prev = (entry_ptr); \ - } \ - (cache_ptr)->index[k] = (entry_ptr); \ - (cache_ptr)->index_len++; \ - (cache_ptr)->index_size += (entry_ptr)->size; \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring]++; \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ - if((entry_ptr)->is_dirty) { \ - (cache_ptr)->dirty_index_size += (entry_ptr)->size; \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ - } else { \ - (cache_ptr)->clean_index_size += (entry_ptr)->size; \ - (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ - } \ - if((entry_ptr)->flush_me_last) { \ - (cache_ptr)->num_last_entries++; \ - assert((cache_ptr)->num_last_entries <= 2); \ - } \ - H5C__IL_DLL_APPEND((entry_ptr), (cache_ptr)->il_head, \ - (cache_ptr)->il_tail, (cache_ptr)->il_len, \ - (cache_ptr)->il_size, fail_val); \ - H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr); \ - H5C__POST_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val); \ -} while (0) - -#define H5C__DELETE_FROM_INDEX(cache_ptr, entry_ptr, fail_val) \ -do { \ - int k; \ - H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr, fail_val) \ - k = H5C__HASH_FCN((entry_ptr)->addr); \ - if((entry_ptr)->ht_next) \ - (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ - if((entry_ptr)->ht_prev) \ - (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ - if((cache_ptr)->index[k] == (entry_ptr)) \ - (cache_ptr)->index[k] = (entry_ptr)->ht_next; \ - (entry_ptr)->ht_next = NULL; \ - (entry_ptr)->ht_prev = NULL; \ - (cache_ptr)->index_len--; \ - (cache_ptr)->index_size -= (entry_ptr)->size; \ - (cache_ptr)->index_ring_len[(entry_ptr)->ring]--; \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ - if((entry_ptr)->is_dirty) { \ - (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ - } else { \ - (cache_ptr)->clean_index_size -= (entry_ptr)->size; \ - (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ - } \ - if((entry_ptr)->flush_me_last) { \ - (cache_ptr)->num_last_entries--; \ - assert((cache_ptr)->num_last_entries <= 1); \ - } \ - H5C__IL_DLL_REMOVE((entry_ptr), (cache_ptr)->il_head, \ - (cache_ptr)->il_tail, (cache_ptr)->il_len, \ - (cache_ptr)->il_size, fail_val); \ - H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr); \ - H5C__POST_HT_REMOVE_SC(cache_ptr, entry_ptr, fail_val); \ -} while (0) - -#define H5C__SEARCH_INDEX(cache_ptr, entry_addr, entry_ptr, fail_val) \ -do { \ - int k; \ - int depth = 0; \ - H5C__PRE_HT_SEARCH_SC(cache_ptr, entry_addr, fail_val); \ - k = H5C__HASH_FCN(entry_addr); \ - (entry_ptr) = (cache_ptr)->index[k]; \ - while(entry_ptr) { \ - if(H5_addr_eq(entry_addr, (entry_ptr)->addr)) { \ - H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, k, fail_val); \ - if((entry_ptr) != (cache_ptr)->index[k]) { \ - if((entry_ptr)->ht_next) \ - (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ - assert((entry_ptr)->ht_prev != NULL); \ - (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ - (cache_ptr)->index[k]->ht_prev = (entry_ptr); \ - (entry_ptr)->ht_next = (cache_ptr)->index[k]; \ - (entry_ptr)->ht_prev = NULL; \ - (cache_ptr)->index[k] = (entry_ptr); \ - H5C__POST_HT_SHIFT_TO_FRONT_SC(cache_ptr, entry_ptr, k, fail_val); \ - } \ - break; \ - } \ - (entry_ptr) = (entry_ptr)->ht_next; \ - (depth)++; \ - } \ - H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, ((entry_ptr) != NULL), depth); \ -} while (0) - -#define H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN(cache_ptr, entry_ptr, fail_val) \ -do { \ - H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr, fail_val); \ - (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ - (cache_ptr)->clean_index_size += (entry_ptr)->size; \ - (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ - H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr, fail_val); \ -} while (0) - -#define H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr, fail_val) \ -do { \ - H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr, fail_val); \ - (cache_ptr)->clean_index_size -= (entry_ptr)->size; \ - (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ - (cache_ptr)->dirty_index_size += (entry_ptr)->size; \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ - H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr, fail_val); \ -} while (0) - -#define H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size, \ - entry_ptr, was_clean, fail_val) \ -do { \ - H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ - entry_ptr, was_clean, fail_val); \ - (cache_ptr)->index_size -= (old_size); \ - (cache_ptr)->index_size += (new_size); \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] -= (old_size); \ - (cache_ptr)->index_ring_size[(entry_ptr)->ring] += (new_size); \ - if(was_clean) { \ - (cache_ptr)->clean_index_size -= (old_size); \ - (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] -= (old_size); \ - } else { \ - (cache_ptr)->dirty_index_size -= (old_size); \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] -= (old_size); \ - } \ - if((entry_ptr)->is_dirty) { \ - (cache_ptr)->dirty_index_size += (new_size); \ - (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] += (new_size); \ - } else { \ - (cache_ptr)->clean_index_size += (new_size); \ - (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] += (new_size); \ - } \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->il_len, \ - (cache_ptr)->il_size, \ - (old_size), (new_size), (fail_val)); \ - H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ - entry_ptr, fail_val); \ -} while (0) - +#define H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, fail_val) \ + do { \ + int k; \ + H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ + k = H5C__HASH_FCN((entry_ptr)->addr); \ + if ((cache_ptr)->index[k] != NULL) { \ + (entry_ptr)->ht_next = (cache_ptr)->index[k]; \ + (entry_ptr)->ht_next->ht_prev = (entry_ptr); \ + } \ + (cache_ptr)->index[k] = (entry_ptr); \ + (cache_ptr)->index_len++; \ + (cache_ptr)->index_size += (entry_ptr)->size; \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring]++; \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ + if ((entry_ptr)->is_dirty) { \ + (cache_ptr)->dirty_index_size += (entry_ptr)->size; \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ + } \ + else { \ + (cache_ptr)->clean_index_size += (entry_ptr)->size; \ + (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ + } \ + if ((entry_ptr)->flush_me_last) { \ + (cache_ptr)->num_last_entries++; \ + assert((cache_ptr)->num_last_entries <= 2); \ + } \ + H5C__IL_DLL_APPEND((entry_ptr), (cache_ptr)->il_head, (cache_ptr)->il_tail, (cache_ptr)->il_len, \ + (cache_ptr)->il_size, fail_val); \ + H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr); \ + H5C__POST_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val); \ + } while (0) + +#define H5C__DELETE_FROM_INDEX(cache_ptr, entry_ptr, fail_val) \ + do { \ + int k; \ + H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr, fail_val) \ + k = H5C__HASH_FCN((entry_ptr)->addr); \ + if ((entry_ptr)->ht_next) \ + (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ + if ((entry_ptr)->ht_prev) \ + (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ + if ((cache_ptr)->index[k] == (entry_ptr)) \ + (cache_ptr)->index[k] = (entry_ptr)->ht_next; \ + (entry_ptr)->ht_next = NULL; \ + (entry_ptr)->ht_prev = NULL; \ + (cache_ptr)->index_len--; \ + (cache_ptr)->index_size -= (entry_ptr)->size; \ + (cache_ptr)->index_ring_len[(entry_ptr)->ring]--; \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ + if ((entry_ptr)->is_dirty) { \ + (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ + } \ + else { \ + (cache_ptr)->clean_index_size -= (entry_ptr)->size; \ + (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ + } \ + if ((entry_ptr)->flush_me_last) { \ + (cache_ptr)->num_last_entries--; \ + assert((cache_ptr)->num_last_entries <= 1); \ + } \ + H5C__IL_DLL_REMOVE((entry_ptr), (cache_ptr)->il_head, (cache_ptr)->il_tail, (cache_ptr)->il_len, \ + (cache_ptr)->il_size, fail_val); \ + H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr); \ + H5C__POST_HT_REMOVE_SC(cache_ptr, entry_ptr, fail_val); \ + } while (0) + +#define H5C__SEARCH_INDEX(cache_ptr, entry_addr, entry_ptr, fail_val) \ + do { \ + int k; \ + int depth = 0; \ + H5C__PRE_HT_SEARCH_SC(cache_ptr, entry_addr, fail_val); \ + k = H5C__HASH_FCN(entry_addr); \ + (entry_ptr) = (cache_ptr)->index[k]; \ + while (entry_ptr) { \ + if (H5_addr_eq(entry_addr, (entry_ptr)->addr)) { \ + H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, k, fail_val); \ + if ((entry_ptr) != (cache_ptr)->index[k]) { \ + if ((entry_ptr)->ht_next) \ + (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ + assert((entry_ptr)->ht_prev != NULL); \ + (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ + (cache_ptr)->index[k]->ht_prev = (entry_ptr); \ + (entry_ptr)->ht_next = (cache_ptr)->index[k]; \ + (entry_ptr)->ht_prev = NULL; \ + (cache_ptr)->index[k] = (entry_ptr); \ + H5C__POST_HT_SHIFT_TO_FRONT_SC(cache_ptr, entry_ptr, k, fail_val); \ + } \ + break; \ + } \ + (entry_ptr) = (entry_ptr)->ht_next; \ + (depth)++; \ + } \ + H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, ((entry_ptr) != NULL), depth); \ + } while (0) + +#define H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN(cache_ptr, entry_ptr, fail_val) \ + do { \ + H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr, fail_val); \ + (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ + (cache_ptr)->clean_index_size += (entry_ptr)->size; \ + (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ + H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr, fail_val); \ + } while (0) + +#define H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr, fail_val) \ + do { \ + H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr, fail_val); \ + (cache_ptr)->clean_index_size -= (entry_ptr)->size; \ + (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] -= (entry_ptr)->size; \ + (cache_ptr)->dirty_index_size += (entry_ptr)->size; \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] += (entry_ptr)->size; \ + H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr, fail_val); \ + } while (0) + +#define H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size, entry_ptr, was_clean, fail_val) \ + do { \ + H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, entry_ptr, was_clean, fail_val); \ + (cache_ptr)->index_size -= (old_size); \ + (cache_ptr)->index_size += (new_size); \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] -= (old_size); \ + (cache_ptr)->index_ring_size[(entry_ptr)->ring] += (new_size); \ + if (was_clean) { \ + (cache_ptr)->clean_index_size -= (old_size); \ + (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] -= (old_size); \ + } \ + else { \ + (cache_ptr)->dirty_index_size -= (old_size); \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] -= (old_size); \ + } \ + if ((entry_ptr)->is_dirty) { \ + (cache_ptr)->dirty_index_size += (new_size); \ + (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring] += (new_size); \ + } \ + else { \ + (cache_ptr)->clean_index_size += (new_size); \ + (cache_ptr)->clean_index_ring_size[(entry_ptr)->ring] += (new_size); \ + } \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->il_len, (cache_ptr)->il_size, (old_size), (new_size), \ + (fail_val)); \ + H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, entry_ptr, fail_val); \ + } while (0) /************************************************************************** * @@ -996,8 +967,7 @@ do { \ #ifdef H5C_DO_SLIST_SANITY_CHECKS -#define H5C__ENTRY_IN_SLIST(cache_ptr, entry_ptr) \ - H5C__entry_in_skip_list((cache_ptr), (entry_ptr)) +#define H5C__ENTRY_IN_SLIST(cache_ptr, entry_ptr) H5C__entry_in_skip_list((cache_ptr), (entry_ptr)) #else /* H5C_DO_SLIST_SANITY_CHECKS */ @@ -1005,24 +975,23 @@ do { \ #endif /* H5C_DO_SLIST_SANITY_CHECKS */ - #ifdef H5C_DO_SANITY_CHECKS -#define H5C__SLIST_INSERT_ENTRY_SC(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->slist_len_increase++; \ - (cache_ptr)->slist_size_increase += (int64_t)((entry_ptr)->size); \ -} while (0) /* H5C__SLIST_INSERT_ENTRY_SC() */ -#define H5C__SLIST_REMOVE_ENTRY_SC(cache_ptr, entry_ptr) \ -do { \ - (cache_ptr)->slist_len_increase--; \ - (cache_ptr)->slist_size_increase -= (int64_t)((entry_ptr)->size); \ -} while (0) /* H5C__SLIST_REMOVE_ENTRY_SC() */ -#define H5C__SLIST_UPDATE_FOR_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size) \ -do { \ - (cache_ptr)->slist_size_increase -= (int64_t)(old_size); \ - (cache_ptr)->slist_size_increase += (int64_t)(new_size); \ -} while (0) /* H5C__SLIST_UPDATE_FOR_ENTRY_SIZE_CHANGE_SC() */ +#define H5C__SLIST_INSERT_ENTRY_SC(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->slist_len_increase++; \ + (cache_ptr)->slist_size_increase += (int64_t)((entry_ptr)->size); \ + } while (0) /* H5C__SLIST_INSERT_ENTRY_SC() */ +#define H5C__SLIST_REMOVE_ENTRY_SC(cache_ptr, entry_ptr) \ + do { \ + (cache_ptr)->slist_len_increase--; \ + (cache_ptr)->slist_size_increase -= (int64_t)((entry_ptr)->size); \ + } while (0) /* H5C__SLIST_REMOVE_ENTRY_SC() */ +#define H5C__SLIST_UPDATE_FOR_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size) \ + do { \ + (cache_ptr)->slist_size_increase -= (int64_t)(old_size); \ + (cache_ptr)->slist_size_increase += (int64_t)(new_size); \ + } while (0) /* H5C__SLIST_UPDATE_FOR_ENTRY_SIZE_CHANGE_SC() */ #else /* H5C_DO_SANITY_CHECKS */ @@ -1032,7 +1001,6 @@ do { \ #endif /* H5C_DO_SANITY_CHECKS */ - /*------------------------------------------------------------------------- * * Macro: H5C__INSERT_ENTRY_IN_SLIST @@ -1046,43 +1014,41 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - \ - if((cache_ptr)->slist_enabled) { \ - assert(entry_ptr); \ - assert((entry_ptr)->size > 0); \ - assert(H5_addr_defined((entry_ptr)->addr)); \ - assert(!(entry_ptr)->in_slist); \ - assert(!H5C__ENTRY_IN_SLIST((cache_ptr), (entry_ptr))); \ - assert((entry_ptr)->ring > H5C_RING_UNDEFINED); \ - assert((entry_ptr)->ring < H5C_RING_NTYPES); \ - assert((cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \ - (cache_ptr)->slist_len); \ - assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \ - (cache_ptr)->slist_size); \ - assert((cache_ptr)->slist_ptr); \ - \ - if(H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, &((entry_ptr)->addr)) < 0) \ - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), "can't insert entry in skip list"); \ - \ - (entry_ptr)->in_slist = true; \ - (cache_ptr)->slist_changed = true; \ - (cache_ptr)->slist_len++; \ - (cache_ptr)->slist_size += (entry_ptr)->size; \ - ((cache_ptr)->slist_ring_len[(entry_ptr)->ring])++; \ - ((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (entry_ptr)->size;\ - H5C__SLIST_INSERT_ENTRY_SC(cache_ptr, entry_ptr); \ - \ - assert((cache_ptr)->slist_len > 0); \ - assert((cache_ptr)->slist_size > 0); \ - } else { /* slist disabled */ \ - assert((cache_ptr)->slist_len == 0); \ - assert((cache_ptr)->slist_size == 0); \ - } \ -} while (0) /* H5C__INSERT_ENTRY_IN_SLIST */ - +#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + \ + if ((cache_ptr)->slist_enabled) { \ + assert(entry_ptr); \ + assert((entry_ptr)->size > 0); \ + assert(H5_addr_defined((entry_ptr)->addr)); \ + assert(!(entry_ptr)->in_slist); \ + assert(!H5C__ENTRY_IN_SLIST((cache_ptr), (entry_ptr))); \ + assert((entry_ptr)->ring > H5C_RING_UNDEFINED); \ + assert((entry_ptr)->ring < H5C_RING_NTYPES); \ + assert((cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= (cache_ptr)->slist_len); \ + assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= (cache_ptr)->slist_size); \ + assert((cache_ptr)->slist_ptr); \ + \ + if (H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, &((entry_ptr)->addr)) < 0) \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), "can't insert entry in skip list"); \ + \ + (entry_ptr)->in_slist = true; \ + (cache_ptr)->slist_changed = true; \ + (cache_ptr)->slist_len++; \ + (cache_ptr)->slist_size += (entry_ptr)->size; \ + ((cache_ptr)->slist_ring_len[(entry_ptr)->ring])++; \ + ((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (entry_ptr)->size; \ + H5C__SLIST_INSERT_ENTRY_SC(cache_ptr, entry_ptr); \ + \ + assert((cache_ptr)->slist_len > 0); \ + assert((cache_ptr)->slist_size > 0); \ + } \ + else { /* slist disabled */ \ + assert((cache_ptr)->slist_len == 0); \ + assert((cache_ptr)->slist_size == 0); \ + } \ + } while (0) /* H5C__INSERT_ENTRY_IN_SLIST */ /*------------------------------------------------------------------------- * @@ -1094,45 +1060,43 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush, fail_val) \ -do { \ - assert(cache_ptr); \ - \ - if((cache_ptr)->slist_enabled) { \ - assert(entry_ptr); \ - assert(!(entry_ptr)->is_read_only); \ - assert((entry_ptr)->ro_ref_count == 0); \ - assert((entry_ptr)->size > 0); \ - assert((entry_ptr)->in_slist); \ - assert((cache_ptr)->slist_ptr); \ - assert((entry_ptr)->ring > H5C_RING_UNDEFINED); \ - assert((entry_ptr)->ring < H5C_RING_NTYPES); \ - assert((cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \ - (cache_ptr)->slist_len); \ - assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \ - (cache_ptr)->slist_size); \ - assert((cache_ptr)->slist_size >= (entry_ptr)->size); \ - \ - if(H5SL_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) != (entry_ptr) ) \ - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), "can't delete entry from skip list"); \ - \ - assert((cache_ptr)->slist_len > 0); \ - if(!(during_flush)) \ - (cache_ptr)->slist_changed = true; \ - (cache_ptr)->slist_len--; \ - assert((cache_ptr)->slist_size >= (entry_ptr)->size); \ - (cache_ptr)->slist_size -= (entry_ptr)->size; \ - (cache_ptr)->slist_ring_len[(entry_ptr)->ring]--; \ - assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] >= (entry_ptr)->size); \ - ((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (entry_ptr)->size;\ - H5C__SLIST_REMOVE_ENTRY_SC(cache_ptr, entry_ptr); \ - (entry_ptr)->in_slist = false; \ - } else { /* slist disabled */ \ - assert((cache_ptr)->slist_len == 0); \ - assert((cache_ptr)->slist_size == 0); \ - } \ -} while (0) /* H5C__REMOVE_ENTRY_FROM_SLIST */ - +#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush, fail_val) \ + do { \ + assert(cache_ptr); \ + \ + if ((cache_ptr)->slist_enabled) { \ + assert(entry_ptr); \ + assert(!(entry_ptr)->is_read_only); \ + assert((entry_ptr)->ro_ref_count == 0); \ + assert((entry_ptr)->size > 0); \ + assert((entry_ptr)->in_slist); \ + assert((cache_ptr)->slist_ptr); \ + assert((entry_ptr)->ring > H5C_RING_UNDEFINED); \ + assert((entry_ptr)->ring < H5C_RING_NTYPES); \ + assert((cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= (cache_ptr)->slist_len); \ + assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= (cache_ptr)->slist_size); \ + assert((cache_ptr)->slist_size >= (entry_ptr)->size); \ + \ + if (H5SL_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) != (entry_ptr)) \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), "can't delete entry from skip list"); \ + \ + assert((cache_ptr)->slist_len > 0); \ + if (!(during_flush)) \ + (cache_ptr)->slist_changed = true; \ + (cache_ptr)->slist_len--; \ + assert((cache_ptr)->slist_size >= (entry_ptr)->size); \ + (cache_ptr)->slist_size -= (entry_ptr)->size; \ + (cache_ptr)->slist_ring_len[(entry_ptr)->ring]--; \ + assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] >= (entry_ptr)->size); \ + ((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (entry_ptr)->size; \ + H5C__SLIST_REMOVE_ENTRY_SC(cache_ptr, entry_ptr); \ + (entry_ptr)->in_slist = false; \ + } \ + else { /* slist disabled */ \ + assert((cache_ptr)->slist_len == 0); \ + assert((cache_ptr)->slist_size == 0); \ + } \ + } while (0) /* H5C__REMOVE_ENTRY_FROM_SLIST */ /*------------------------------------------------------------------------- * @@ -1144,43 +1108,39 @@ do { *------------------------------------------------------------------------- */ -#define H5C__UPDATE_SLIST_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size) \ -do { \ - assert(cache_ptr); \ - \ - if((cache_ptr)->slist_enabled) { \ - assert((old_size) > 0); \ - assert((new_size) > 0); \ - assert((old_size) <= (cache_ptr)->slist_size); \ - assert((cache_ptr)->slist_len > 0); \ - assert((cache_ptr)->slist_len > 1 || \ - (cache_ptr)->slist_size == (old_size)); \ - assert((entry_ptr)->ring > H5C_RING_UNDEFINED); \ - assert((entry_ptr)->ring < H5C_RING_NTYPES); \ - assert((cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \ - (cache_ptr)->slist_len); \ - assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \ - (cache_ptr)->slist_size); \ - \ - (cache_ptr)->slist_size -= (old_size); \ - (cache_ptr)->slist_size += (new_size); \ - \ - assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] >= (old_size)); \ - \ - (cache_ptr)->slist_ring_size[(entry_ptr)->ring] -= (old_size); \ - (cache_ptr)->slist_ring_size[(entry_ptr)->ring] += (new_size); \ - \ - H5C__SLIST_UPDATE_FOR_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size); \ - \ - assert((new_size) <= (cache_ptr)->slist_size); \ - assert((cache_ptr)->slist_len > 1 || \ - (cache_ptr)->slist_size == (new_size)); \ - } else { /* slist disabled */ \ - assert((cache_ptr)->slist_len == 0); \ - assert((cache_ptr)->slist_size == 0); \ - } \ -} while (0) /* H5C__UPDATE_SLIST_FOR_SIZE_CHANGE */ - +#define H5C__UPDATE_SLIST_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size) \ + do { \ + assert(cache_ptr); \ + \ + if ((cache_ptr)->slist_enabled) { \ + assert((old_size) > 0); \ + assert((new_size) > 0); \ + assert((old_size) <= (cache_ptr)->slist_size); \ + assert((cache_ptr)->slist_len > 0); \ + assert((cache_ptr)->slist_len > 1 || (cache_ptr)->slist_size == (old_size)); \ + assert((entry_ptr)->ring > H5C_RING_UNDEFINED); \ + assert((entry_ptr)->ring < H5C_RING_NTYPES); \ + assert((cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= (cache_ptr)->slist_len); \ + assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= (cache_ptr)->slist_size); \ + \ + (cache_ptr)->slist_size -= (old_size); \ + (cache_ptr)->slist_size += (new_size); \ + \ + assert((cache_ptr)->slist_ring_size[(entry_ptr)->ring] >= (old_size)); \ + \ + (cache_ptr)->slist_ring_size[(entry_ptr)->ring] -= (old_size); \ + (cache_ptr)->slist_ring_size[(entry_ptr)->ring] += (new_size); \ + \ + H5C__SLIST_UPDATE_FOR_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size); \ + \ + assert((new_size) <= (cache_ptr)->slist_size); \ + assert((cache_ptr)->slist_len > 1 || (cache_ptr)->slist_size == (new_size)); \ + } \ + else { /* slist disabled */ \ + assert((cache_ptr)->slist_len == 0); \ + assert((cache_ptr)->slist_size == 0); \ + } \ + } while (0) /* H5C__UPDATE_SLIST_FOR_SIZE_CHANGE */ /************************************************************************** * @@ -1190,201 +1150,162 @@ do { \ #if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS -#define H5C__UPDATE_RP_FOR_EVICTION_CD_LRU(cache_ptr, entry_ptr, fail_val) \ -do { \ - /* If the entry is clean when it is evicted, it should be on the \ - * clean LRU list, if it was dirty, it should be on the dirty LRU list. \ - * Remove it from the appropriate list according to the value of the \ - * dirty flag. \ - */ \ - if((entry_ptr)->is_dirty) { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_EVICTION_CD_LRU() */ - -#define H5C__UPDATE_RP_FOR_FLUSH_CD_LRU(cache_ptr, entry_ptr, fail_val) \ -do { \ - /* An entry being flushed or cleared, may not be dirty. Use the \ - * dirty flag to infer whether the entry is on the clean or dirty \ - * LRU list, and remove it. Then insert it at the head of the \ - * clean LRU list. \ - * \ - * The function presumes that a dirty entry will be either cleared \ - * or flushed shortly, so it is OK if we put a dirty entry on the \ - * clean LRU list. \ - */ \ - if((entry_ptr)->is_dirty) { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ -} while (0) /* H5C__UPDATE_RP_FOR_FLUSH_CD_LRU() */ - -#define H5C__UPDATE_RP_FOR_INSERT_APPEND_CD_LRU(cache_ptr, entry_ptr, fail_val) \ -do { \ - /* Insert the entry at the _tail_ of the clean or dirty LRU list as \ - * appropriate. \ - */ \ - if((entry_ptr)->is_dirty) { \ - H5C__AUX_DLL_APPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)); \ - } else { \ - H5C__AUX_DLL_APPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)); \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_INSERT_APPEND_CD_LRU() */ - -#define H5C__UPDATE_RP_FOR_INSERTION_CD_LRU(cache_ptr, entry_ptr, fail_val) \ -do { \ - /* Insert the entry at the head of the clean or dirty LRU list as \ - * appropriate. \ - */ \ - if((entry_ptr)->is_dirty) { \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ -} while(0) /* H5C__UPDATE_RP_FOR_INSERTION_CD_LRU() */ - -#define H5C__UPDATE_RP_FOR_PROTECT_CD_LRU(cache_ptr, entry_ptr, fail_val) \ -{ \ - /* Remove the entry from the clean or dirty LRU list as appropriate */ \ - if((entry_ptr)->is_dirty) { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_PROTECT_CD_LRU() */ - -#define H5C__UPDATE_RP_FOR_MOVE_CD_LRU(cache_ptr, entry_ptr, was_dirty, fail_val) \ -do { \ - /* Remove the entry from either the clean or dirty LRU list as \ - * indicated by the was_dirty parameter \ - */ \ - if(was_dirty) { \ - H5C__AUX_DLL_REMOVE((entry_ptr), \ - (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)); \ - \ - } else { \ - H5C__AUX_DLL_REMOVE((entry_ptr), \ - (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)); \ - } \ - \ - /* Insert the entry at the head of either the clean or dirty \ - * LRU list as appropriate. \ - */ \ - if((entry_ptr)->is_dirty) { \ - H5C__AUX_DLL_PREPEND((entry_ptr), \ - (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)); \ - } else { \ - H5C__AUX_DLL_PREPEND((entry_ptr), \ - (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)); \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_MOVE_CD_LRU() */ - -#define H5C__UPDATE_RP_FOR_SIZE_CHANGE_CD_LRU(cache_ptr, entry_ptr, new_size, fail_val) \ -do { \ - /* Update the size of the clean or dirty LRU list as \ - * appropriate. \ - */ \ - if((entry_ptr)->is_dirty) { \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, \ - (entry_ptr)->size, \ - (new_size), (fail_val)) \ - \ - } else { \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, \ - (entry_ptr)->size, \ - (new_size), (fail_val)) \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_SIZE_CHANGE_CD_LRU() */ - -#define H5C__UPDATE_RP_FOR_UNPIN_CD_LRU(cache_ptr, entry_ptr, fail_val) \ -do { \ - /* Insert the entry at the head of either the clean \ - * or dirty LRU list as appropriate. \ - */ \ - if((entry_ptr)->is_dirty) { \ - H5C__AUX_DLL_PREPEND((entry_ptr), \ - (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_PREPEND((entry_ptr), \ - (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_UNPIN_CD_LRU() */ - -#define H5C__UPDATE_RP_FOR_UNPROTECT_CD_LRU(cache_ptr, entry_ptr, fail_val) \ -do { \ - /* Insert the entry at the head of either the clean or \ - * dirty LRU list as appropriate. \ - */ \ - if((entry_ptr)->is_dirty) { \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_UNPROTECT_CD_LRU() */ +#define H5C__UPDATE_RP_FOR_EVICTION_CD_LRU(cache_ptr, entry_ptr, fail_val) \ + do { \ + /* If the entry is clean when it is evicted, it should be on the \ + * clean LRU list, if it was dirty, it should be on the dirty LRU list. \ + * Remove it from the appropriate list according to the value of the \ + * dirty flag. \ + */ \ + if ((entry_ptr)->is_dirty) { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, (fail_val)) \ + } \ + else { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_EVICTION_CD_LRU() */ + +#define H5C__UPDATE_RP_FOR_FLUSH_CD_LRU(cache_ptr, entry_ptr, fail_val) \ + do { \ + /* An entry being flushed or cleared, may not be dirty. Use the \ + * dirty flag to infer whether the entry is on the clean or dirty \ + * LRU list, and remove it. Then insert it at the head of the \ + * clean LRU list. \ + * \ + * The function presumes that a dirty entry will be either cleared \ + * or flushed shortly, so it is OK if we put a dirty entry on the \ + * clean LRU list. \ + */ \ + if ((entry_ptr)->is_dirty) { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, (fail_val)) \ + } \ + else { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)) \ + } while (0) /* H5C__UPDATE_RP_FOR_FLUSH_CD_LRU() */ + +#define H5C__UPDATE_RP_FOR_INSERT_APPEND_CD_LRU(cache_ptr, entry_ptr, fail_val) \ + do { \ + /* Insert the entry at the _tail_ of the clean or dirty LRU list as \ + * appropriate. \ + */ \ + if ((entry_ptr)->is_dirty) { \ + H5C__AUX_DLL_APPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, (fail_val)); \ + } \ + else { \ + H5C__AUX_DLL_APPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)); \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_INSERT_APPEND_CD_LRU() */ + +#define H5C__UPDATE_RP_FOR_INSERTION_CD_LRU(cache_ptr, entry_ptr, fail_val) \ + do { \ + /* Insert the entry at the head of the clean or dirty LRU list as \ + * appropriate. \ + */ \ + if ((entry_ptr)->is_dirty) { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, (fail_val)) \ + } \ + else { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_INSERTION_CD_LRU() */ + +#define H5C__UPDATE_RP_FOR_PROTECT_CD_LRU(cache_ptr, entry_ptr, fail_val) \ + { \ + /* Remove the entry from the clean or dirty LRU list as appropriate */ \ + if ((entry_ptr)->is_dirty) { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, (fail_val)) \ + } \ + else { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + } \ + while (0) /* H5C__UPDATE_RP_FOR_PROTECT_CD_LRU() */ + +#define H5C__UPDATE_RP_FOR_MOVE_CD_LRU(cache_ptr, entry_ptr, was_dirty, fail_val) \ + do { \ + /* Remove the entry from either the clean or dirty LRU list as \ + * indicated by the was_dirty parameter \ + */ \ + if (was_dirty) { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, (fail_val)); \ + } \ + else { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)); \ + } \ + \ + /* Insert the entry at the head of either the clean or dirty \ + * LRU list as appropriate. \ + */ \ + if ((entry_ptr)->is_dirty) { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, (fail_val)); \ + } \ + else { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)); \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_MOVE_CD_LRU() */ + +#define H5C__UPDATE_RP_FOR_SIZE_CHANGE_CD_LRU(cache_ptr, entry_ptr, new_size, fail_val) \ + do { \ + /* Update the size of the clean or dirty LRU list as \ + * appropriate. \ + */ \ + if ((entry_ptr)->is_dirty) { \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, \ + (entry_ptr)->size, (new_size), (fail_val)) \ + } \ + else { \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, \ + (entry_ptr)->size, (new_size), (fail_val)) \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_SIZE_CHANGE_CD_LRU() */ + +#define H5C__UPDATE_RP_FOR_UNPIN_CD_LRU(cache_ptr, entry_ptr, fail_val) \ + do { \ + /* Insert the entry at the head of either the clean \ + * or dirty LRU list as appropriate. \ + */ \ + if ((entry_ptr)->is_dirty) { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, (fail_val)) \ + } \ + else { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_UNPIN_CD_LRU() */ + +#define H5C__UPDATE_RP_FOR_UNPROTECT_CD_LRU(cache_ptr, entry_ptr, fail_val) \ + do { \ + /* Insert the entry at the head of either the clean or \ + * dirty LRU list as appropriate. \ + */ \ + if ((entry_ptr)->is_dirty) { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, (cache_ptr)->dLRU_list_size, (fail_val)) \ + } \ + else { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_UNPROTECT_CD_LRU() */ #else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ @@ -1410,25 +1331,23 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__UPDATE_RP_FOR_EVICTION(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - assert(!(entry_ptr)->is_protected); \ - assert(!(entry_ptr)->is_read_only); \ - assert((entry_ptr)->ro_ref_count == 0); \ - assert(!(entry_ptr)->is_pinned); \ - assert((entry_ptr)->size > 0); \ - \ - /* Remove the entry from the LRU list */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Remove the entry from the clean & dirty LRU lists, if enabled */ \ - H5C__UPDATE_RP_FOR_EVICTION_CD_LRU(cache_ptr, entry_ptr, fail_val); \ -} while (0) /* H5C__UPDATE_RP_FOR_EVICTION */ - +#define H5C__UPDATE_RP_FOR_EVICTION(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + assert(!(entry_ptr)->is_protected); \ + assert(!(entry_ptr)->is_read_only); \ + assert((entry_ptr)->ro_ref_count == 0); \ + assert(!(entry_ptr)->is_pinned); \ + assert((entry_ptr)->size > 0); \ + \ + /* Remove the entry from the LRU list */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Remove the entry from the clean & dirty LRU lists, if enabled */ \ + H5C__UPDATE_RP_FOR_EVICTION_CD_LRU(cache_ptr, entry_ptr, fail_val); \ + } while (0) /* H5C__UPDATE_RP_FOR_EVICTION */ /*------------------------------------------------------------------------- * @@ -1440,34 +1359,29 @@ do { *------------------------------------------------------------------------- */ -#define H5C__UPDATE_RP_FOR_FLUSH(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - assert(!(entry_ptr)->is_protected); \ - assert(!(entry_ptr)->is_read_only); \ - assert((entry_ptr)->ro_ref_count == 0); \ - assert((entry_ptr)->size > 0); \ - \ - if(!(entry_ptr)->is_pinned) { \ - /* Remove the entry from its location in the LRU list \ - * and re-insert it at the head of the list. \ - */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Maintain the clean & dirty LRU lists, if enabled */ \ - H5C__UPDATE_RP_FOR_FLUSH_CD_LRU(cache_ptr, entry_ptr, fail_val); \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_FLUSH */ - +#define H5C__UPDATE_RP_FOR_FLUSH(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + assert(!(entry_ptr)->is_protected); \ + assert(!(entry_ptr)->is_read_only); \ + assert((entry_ptr)->ro_ref_count == 0); \ + assert((entry_ptr)->size > 0); \ + \ + if (!(entry_ptr)->is_pinned) { \ + /* Remove the entry from its location in the LRU list \ + * and re-insert it at the head of the list. \ + */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Maintain the clean & dirty LRU lists, if enabled */ \ + H5C__UPDATE_RP_FOR_FLUSH_CD_LRU(cache_ptr, entry_ptr, fail_val); \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_FLUSH */ /*------------------------------------------------------------------------- * @@ -1483,32 +1397,28 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__UPDATE_RP_FOR_INSERT_APPEND(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - assert(!(entry_ptr)->is_protected); \ - assert(!(entry_ptr)->is_read_only); \ - assert((entry_ptr)->ro_ref_count == 0 ); \ - assert((entry_ptr)->size > 0 ); \ - \ - if((entry_ptr)->is_pinned) { \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - } else { \ - /* Insert the entry at the tail of the LRU list. */ \ - H5C__DLL_APPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Maintain the clean & dirty LRU lists, if enabled */ \ - H5C__UPDATE_RP_FOR_INSERT_APPEND_CD_LRU(cache_ptr, entry_ptr, fail_val); \ - } \ -} while (0) - +#define H5C__UPDATE_RP_FOR_INSERT_APPEND(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + assert(!(entry_ptr)->is_protected); \ + assert(!(entry_ptr)->is_read_only); \ + assert((entry_ptr)->ro_ref_count == 0); \ + assert((entry_ptr)->size > 0); \ + \ + if ((entry_ptr)->is_pinned) { \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, (cache_ptr)->pel_size, (fail_val)) \ + } \ + else { \ + /* Insert the entry at the tail of the LRU list. */ \ + H5C__DLL_APPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Maintain the clean & dirty LRU lists, if enabled */ \ + H5C__UPDATE_RP_FOR_INSERT_APPEND_CD_LRU(cache_ptr, entry_ptr, fail_val); \ + } \ + } while (0) /*------------------------------------------------------------------------- * @@ -1520,33 +1430,28 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - assert(!(entry_ptr)->is_protected); \ - assert(!(entry_ptr)->is_read_only); \ - assert((entry_ptr)->ro_ref_count == 0); \ - assert((entry_ptr)->size > 0); \ - \ - if((entry_ptr)->is_pinned) { \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - \ - } else { \ - /* Insert the entry at the head of the LRU list. */ \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Maintain the clean & dirty LRU lists, if enabled */ \ - H5C__UPDATE_RP_FOR_INSERTION_CD_LRU(cache_ptr, entry_ptr, fail_val); \ - } \ -} while (0) - +#define H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + assert(!(entry_ptr)->is_protected); \ + assert(!(entry_ptr)->is_read_only); \ + assert((entry_ptr)->ro_ref_count == 0); \ + assert((entry_ptr)->size > 0); \ + \ + if ((entry_ptr)->is_pinned) { \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, (cache_ptr)->pel_size, (fail_val)) \ + } \ + else { \ + /* Insert the entry at the head of the LRU list. */ \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Maintain the clean & dirty LRU lists, if enabled */ \ + H5C__UPDATE_RP_FOR_INSERTION_CD_LRU(cache_ptr, entry_ptr, fail_val); \ + } \ + } while (0) /*------------------------------------------------------------------------- * @@ -1563,40 +1468,34 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__UPDATE_RP_FOR_PROTECT(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - assert(!(entry_ptr)->is_protected); \ - assert(!(entry_ptr)->is_read_only); \ - assert((entry_ptr)->ro_ref_count == 0); \ - assert((entry_ptr)->size > 0); \ - \ - if((entry_ptr)->is_pinned) { \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - } else { \ - /* Remove the entry from the LRU list. */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Maintain the clean & dirty LRU lists, if enabled */ \ - H5C__UPDATE_RP_FOR_PROTECT_CD_LRU(cache_ptr, entry_ptr, fail_val); \ - } \ - \ - /* Regardless of whether the entry is pinned, add it to the protected \ - * list. \ - */ \ - H5C__DLL_APPEND((entry_ptr), (cache_ptr)->pl_head_ptr, \ - (cache_ptr)->pl_tail_ptr, \ - (cache_ptr)->pl_len, \ - (cache_ptr)->pl_size, (fail_val)) \ -} while (0) /* H5C__UPDATE_RP_FOR_PROTECT */ - +#define H5C__UPDATE_RP_FOR_PROTECT(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + assert(!(entry_ptr)->is_protected); \ + assert(!(entry_ptr)->is_read_only); \ + assert((entry_ptr)->ro_ref_count == 0); \ + assert((entry_ptr)->size > 0); \ + \ + if ((entry_ptr)->is_pinned) { \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, (cache_ptr)->pel_size, (fail_val)) \ + } \ + else { \ + /* Remove the entry from the LRU list. */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Maintain the clean & dirty LRU lists, if enabled */ \ + H5C__UPDATE_RP_FOR_PROTECT_CD_LRU(cache_ptr, entry_ptr, fail_val); \ + } \ + \ + /* Regardless of whether the entry is pinned, add it to the protected \ + * list. \ + */ \ + H5C__DLL_APPEND((entry_ptr), (cache_ptr)->pl_head_ptr, (cache_ptr)->pl_tail_ptr, \ + (cache_ptr)->pl_len, (cache_ptr)->pl_size, (fail_val)) \ + } while (0) /* H5C__UPDATE_RP_FOR_PROTECT */ /*------------------------------------------------------------------------- * @@ -1608,32 +1507,27 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__UPDATE_RP_FOR_MOVE(cache_ptr, entry_ptr, was_dirty, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - assert(!(entry_ptr)->is_read_only); \ - assert((entry_ptr)->ro_ref_count == 0); \ - assert((entry_ptr)->size > 0); \ - \ - if(!(entry_ptr)->is_pinned && !(entry_ptr)->is_protected) { \ - /* Remove the entry from the LRU list, and re-insert it at the head. \ - */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Maintain the clean & dirty LRU lists, if enabled */ \ - H5C__UPDATE_RP_FOR_MOVE_CD_LRU(cache_ptr, entry_ptr, was_dirty, fail_val); \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_MOVE */ - +#define H5C__UPDATE_RP_FOR_MOVE(cache_ptr, entry_ptr, was_dirty, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + assert(!(entry_ptr)->is_read_only); \ + assert((entry_ptr)->ro_ref_count == 0); \ + assert((entry_ptr)->size > 0); \ + \ + if (!(entry_ptr)->is_pinned && !(entry_ptr)->is_protected) { \ + /* Remove the entry from the LRU list, and re-insert it at the head. \ + */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Maintain the clean & dirty LRU lists, if enabled */ \ + H5C__UPDATE_RP_FOR_MOVE_CD_LRU(cache_ptr, entry_ptr, was_dirty, fail_val); \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_MOVE */ /*------------------------------------------------------------------------- * @@ -1657,16 +1551,13 @@ do { \ #ifdef H5_HAVE_PARALLEL -#define H5C__UPDATE_RP_FOR_SIZE_CHANGE_COLL(cache_ptr, entry_ptr, new_size, fail_val) \ -do { \ - if((entry_ptr)->coll_access) { \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->coll_list_len, \ - (cache_ptr)->coll_list_size, \ - (entry_ptr)->size, \ - (new_size), (fail_val)); \ - \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_SIZE_CHANGE_COLL() */ +#define H5C__UPDATE_RP_FOR_SIZE_CHANGE_COLL(cache_ptr, entry_ptr, new_size, fail_val) \ + do { \ + if ((entry_ptr)->coll_access) { \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->coll_list_len, (cache_ptr)->coll_list_size, \ + (entry_ptr)->size, (new_size), (fail_val)); \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_SIZE_CHANGE_COLL() */ #else /* H5_HAVE_PARALLEL */ @@ -1674,36 +1565,32 @@ do { \ #endif /* H5_HAVE_PARALLEL */ -#define H5C__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, entry_ptr, new_size, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - assert(!(entry_ptr)->is_protected); \ - assert(!(entry_ptr)->is_read_only); \ - assert((entry_ptr)->ro_ref_count == 0); \ - assert((entry_ptr)->size > 0 ); \ - assert(new_size > 0 ); \ - \ - /* Maintain the collective access list, if enabled */ \ - H5C__UPDATE_RP_FOR_SIZE_CHANGE_COLL(cache_ptr, entry_ptr, new_size, fail_val); \ - \ - if((entry_ptr)->is_pinned) { \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, \ - (entry_ptr)->size, \ - (new_size), (fail_val)) \ - } else { \ - /* Update the size of the LRU list */ \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, \ - (entry_ptr)->size, \ - (new_size), (fail_val)) \ - \ - /* Maintain the clean & dirty LRU lists, if enabled */ \ - H5C__UPDATE_RP_FOR_SIZE_CHANGE_CD_LRU(cache_ptr, entry_ptr, new_size, fail_val); \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_SIZE_CHANGE */ - +#define H5C__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, entry_ptr, new_size, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + assert(!(entry_ptr)->is_protected); \ + assert(!(entry_ptr)->is_read_only); \ + assert((entry_ptr)->ro_ref_count == 0); \ + assert((entry_ptr)->size > 0); \ + assert(new_size > 0); \ + \ + /* Maintain the collective access list, if enabled */ \ + H5C__UPDATE_RP_FOR_SIZE_CHANGE_COLL(cache_ptr, entry_ptr, new_size, fail_val); \ + \ + if ((entry_ptr)->is_pinned) { \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, (cache_ptr)->pel_size, (entry_ptr)->size, \ + (new_size), (fail_val)) \ + } \ + else { \ + /* Update the size of the LRU list */ \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, \ + (entry_ptr)->size, (new_size), (fail_val)) \ + \ + /* Maintain the clean & dirty LRU lists, if enabled */ \ + H5C__UPDATE_RP_FOR_SIZE_CHANGE_CD_LRU(cache_ptr, entry_ptr, new_size, fail_val); \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_SIZE_CHANGE */ /*------------------------------------------------------------------------- * @@ -1719,33 +1606,29 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - assert(!(entry_ptr)->is_protected); \ - assert(!(entry_ptr)->is_read_only); \ - assert((entry_ptr)->ro_ref_count == 0 ); \ - assert((entry_ptr)->is_pinned); \ - assert((entry_ptr)->size > 0); \ - \ - /* Regardless of the replacement policy, remove the entry from the \ - * pinned entry list. \ - */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)); \ - \ - /* Insert the entry at the head of the LRU list. */ \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)); \ - \ - /* Maintain the clean & dirty LRU lists, if enabled */ \ - H5C__UPDATE_RP_FOR_UNPIN_CD_LRU(cache_ptr, entry_ptr, fail_val); \ -} while(0) /* H5C__UPDATE_RP_FOR_UNPIN */ - +#define H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + assert(!(entry_ptr)->is_protected); \ + assert(!(entry_ptr)->is_read_only); \ + assert((entry_ptr)->ro_ref_count == 0); \ + assert((entry_ptr)->is_pinned); \ + assert((entry_ptr)->size > 0); \ + \ + /* Regardless of the replacement policy, remove the entry from the \ + * pinned entry list. \ + */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, (cache_ptr)->pel_size, (fail_val)); \ + \ + /* Insert the entry at the head of the LRU list. */ \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)); \ + \ + /* Maintain the clean & dirty LRU lists, if enabled */ \ + H5C__UPDATE_RP_FOR_UNPIN_CD_LRU(cache_ptr, entry_ptr, fail_val); \ + } while (0) /* H5C__UPDATE_RP_FOR_UNPIN */ /*------------------------------------------------------------------------- * @@ -1761,47 +1644,41 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__UPDATE_RP_FOR_UNPROTECT(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - assert((entry_ptr)->is_protected); \ - assert((entry_ptr)->size > 0); \ - \ - /* Regardless of the replacement policy, remove the entry from the \ - * protected list. \ - */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pl_head_ptr, \ - (cache_ptr)->pl_tail_ptr, (cache_ptr)->pl_len, \ - (cache_ptr)->pl_size, (fail_val)) \ - \ - if((entry_ptr)->is_pinned) { \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - } else { \ - /* Insert the entry at the head of the LRU list. */ \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Maintain the clean & dirty LRU lists, if enabled */ \ - H5C__UPDATE_RP_FOR_UNPROTECT_CD_LRU(cache_ptr, entry_ptr, fail_val); \ - } \ -} while (0) /* H5C__UPDATE_RP_FOR_UNPROTECT */ - +#define H5C__UPDATE_RP_FOR_UNPROTECT(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + assert((entry_ptr)->is_protected); \ + assert((entry_ptr)->size > 0); \ + \ + /* Regardless of the replacement policy, remove the entry from the \ + * protected list. \ + */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pl_head_ptr, (cache_ptr)->pl_tail_ptr, \ + (cache_ptr)->pl_len, (cache_ptr)->pl_size, (fail_val)) \ + \ + if ((entry_ptr)->is_pinned) { \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, (cache_ptr)->pel_size, (fail_val)) \ + } \ + else { \ + /* Insert the entry at the head of the LRU list. */ \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Maintain the clean & dirty LRU lists, if enabled */ \ + H5C__UPDATE_RP_FOR_UNPROTECT_CD_LRU(cache_ptr, entry_ptr, fail_val); \ + } \ + } while (0) /* H5C__UPDATE_RP_FOR_UNPROTECT */ #ifdef H5_HAVE_PARALLEL /* Macros that modify the "collective I/O" LRU list */ -#define H5C__COLL_DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__COLL_DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_PREPEND(entry_ptr, coll_next, coll_prev, head_ptr, tail_ptr, len, list_size, fail_val) -#define H5C__COLL_DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ +#define H5C__COLL_DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, list_size, fail_val) \ H5C__GEN_DLL_REMOVE(entry_ptr, coll_next, coll_prev, head_ptr, tail_ptr, len, list_size, fail_val) - /*------------------------------------------------------------------------- * * Macro: H5C__INSERT_IN_COLL_LIST @@ -1811,18 +1688,15 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__INSERT_IN_COLL_LIST(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - \ - /* Insert the entry at the head of the list. */ \ - H5C__COLL_DLL_PREPEND((entry_ptr), (cache_ptr)->coll_head_ptr, \ - (cache_ptr)->coll_tail_ptr, \ - (cache_ptr)->coll_list_len, \ - (cache_ptr)->coll_list_size, (fail_val)) \ -} while (0) /* H5C__INSERT_IN_COLL_LIST */ - +#define H5C__INSERT_IN_COLL_LIST(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + \ + /* Insert the entry at the head of the list. */ \ + H5C__COLL_DLL_PREPEND((entry_ptr), (cache_ptr)->coll_head_ptr, (cache_ptr)->coll_tail_ptr, \ + (cache_ptr)->coll_list_len, (cache_ptr)->coll_list_size, (fail_val)) \ + } while (0) /* H5C__INSERT_IN_COLL_LIST */ /*------------------------------------------------------------------------- * @@ -1833,18 +1707,15 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__REMOVE_FROM_COLL_LIST(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - \ - /* Remove the entry from the list. */ \ - H5C__COLL_DLL_REMOVE((entry_ptr), (cache_ptr)->coll_head_ptr, \ - (cache_ptr)->coll_tail_ptr, \ - (cache_ptr)->coll_list_len, \ - (cache_ptr)->coll_list_size, (fail_val)) \ -} while (0) /* H5C__REMOVE_FROM_COLL_LIST */ - +#define H5C__REMOVE_FROM_COLL_LIST(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + \ + /* Remove the entry from the list. */ \ + H5C__COLL_DLL_REMOVE((entry_ptr), (cache_ptr)->coll_head_ptr, (cache_ptr)->coll_tail_ptr, \ + (cache_ptr)->coll_list_len, (cache_ptr)->coll_list_size, (fail_val)) \ + } while (0) /* H5C__REMOVE_FROM_COLL_LIST */ /*------------------------------------------------------------------------- * @@ -1855,25 +1726,20 @@ do { \ *------------------------------------------------------------------------- */ -#define H5C__MOVE_TO_TOP_IN_COLL_LIST(cache_ptr, entry_ptr, fail_val) \ -do { \ - assert(cache_ptr); \ - assert(entry_ptr); \ - \ - /* Remove entry and insert at the head of the list. */ \ - H5C__COLL_DLL_REMOVE((entry_ptr), (cache_ptr)->coll_head_ptr, \ - (cache_ptr)->coll_tail_ptr, \ - (cache_ptr)->coll_list_len, \ - (cache_ptr)->coll_list_size, (fail_val)) \ - \ - H5C__COLL_DLL_PREPEND((entry_ptr), (cache_ptr)->coll_head_ptr, \ - (cache_ptr)->coll_tail_ptr, \ - (cache_ptr)->coll_list_len, \ - (cache_ptr)->coll_list_size, (fail_val)) \ - \ -} while (0) /* H5C__MOVE_TO_TOP_IN_COLL_LIST */ -#endif /* H5_HAVE_PARALLEL */ - +#define H5C__MOVE_TO_TOP_IN_COLL_LIST(cache_ptr, entry_ptr, fail_val) \ + do { \ + assert(cache_ptr); \ + assert(entry_ptr); \ + \ + /* Remove entry and insert at the head of the list. */ \ + H5C__COLL_DLL_REMOVE((entry_ptr), (cache_ptr)->coll_head_ptr, (cache_ptr)->coll_tail_ptr, \ + (cache_ptr)->coll_list_len, (cache_ptr)->coll_list_size, (fail_val)) \ + \ + H5C__COLL_DLL_PREPEND((entry_ptr), (cache_ptr)->coll_head_ptr, (cache_ptr)->coll_tail_ptr, \ + (cache_ptr)->coll_list_len, (cache_ptr)->coll_list_size, (fail_val)) \ + \ + } while (0) /* H5C__MOVE_TO_TOP_IN_COLL_LIST */ +#endif /* H5_HAVE_PARALLEL */ /****************************/ /* Package Private Typedefs */ @@ -1908,16 +1774,15 @@ do { \ * ****************************************************************************/ typedef struct H5C_tag_info_t { - haddr_t tag; /* Tag (address) of the entries (must be first, for skiplist) */ - H5C_cache_entry_t *head; /* Head of the list of entries for this tag */ - size_t entry_cnt; /* Number of entries on list */ - bool corked; /* Whether this object is corked */ + haddr_t tag; /* Tag (address) of the entries (must be first, for skiplist) */ + H5C_cache_entry_t *head; /* Head of the list of entries for this tag */ + size_t entry_cnt; /* Number of entries on list */ + bool corked; /* Whether this object is corked */ /* Hash table fields */ - UT_hash_handle hh; /* Hash table handle (must be LAST) */ + UT_hash_handle hh; /* Hash table handle (must be LAST) */ } H5C_tag_info_t; - /**************************************************************************** * * structure H5C_t @@ -2997,237 +2862,237 @@ typedef struct H5C_tag_info_t { * ****************************************************************************/ struct H5C_t { - bool flush_in_progress; - H5C_log_info_t * log_info; - void * aux_ptr; - int32_t max_type_id; - const H5C_class_t * const *class_table_ptr; - size_t max_cache_size; - size_t min_clean_size; + bool flush_in_progress; + H5C_log_info_t *log_info; + void *aux_ptr; + int32_t max_type_id; + const H5C_class_t *const *class_table_ptr; + size_t max_cache_size; + size_t min_clean_size; H5C_write_permitted_func_t check_write_permitted; - bool write_permitted; - H5C_log_flush_func_t log_flush; - bool evictions_enabled; - bool close_warning_received; + bool write_permitted; + H5C_log_flush_func_t log_flush; + bool evictions_enabled; + bool close_warning_received; /* Fields for maintaining the [hash table] index of entries */ - uint32_t index_len; - size_t index_size; - uint32_t index_ring_len[H5C_RING_NTYPES]; - size_t index_ring_size[H5C_RING_NTYPES]; - size_t clean_index_size; - size_t clean_index_ring_size[H5C_RING_NTYPES]; - size_t dirty_index_size; - size_t dirty_index_ring_size[H5C_RING_NTYPES]; - H5C_cache_entry_t * index[H5C__HASH_TABLE_LEN]; - uint32_t il_len; - size_t il_size; - H5C_cache_entry_t * il_head; - H5C_cache_entry_t * il_tail; + uint32_t index_len; + size_t index_size; + uint32_t index_ring_len[H5C_RING_NTYPES]; + size_t index_ring_size[H5C_RING_NTYPES]; + size_t clean_index_size; + size_t clean_index_ring_size[H5C_RING_NTYPES]; + size_t dirty_index_size; + size_t dirty_index_ring_size[H5C_RING_NTYPES]; + H5C_cache_entry_t *index[H5C__HASH_TABLE_LEN]; + uint32_t il_len; + size_t il_size; + H5C_cache_entry_t *il_head; + H5C_cache_entry_t *il_tail; /* Fields to detect entries removed during scans */ - int64_t entries_removed_counter; - H5C_cache_entry_t * last_entry_removed_ptr; - H5C_cache_entry_t * entry_watched_for_removal; + int64_t entries_removed_counter; + H5C_cache_entry_t *last_entry_removed_ptr; + H5C_cache_entry_t *entry_watched_for_removal; /* Fields for maintaining list of in-order entries, for flushing */ - bool slist_enabled; - bool slist_changed; - uint32_t slist_len; - size_t slist_size; - uint32_t slist_ring_len[H5C_RING_NTYPES]; - size_t slist_ring_size[H5C_RING_NTYPES]; - H5SL_t * slist_ptr; - uint32_t num_last_entries; + bool slist_enabled; + bool slist_changed; + uint32_t slist_len; + size_t slist_size; + uint32_t slist_ring_len[H5C_RING_NTYPES]; + size_t slist_ring_size[H5C_RING_NTYPES]; + H5SL_t *slist_ptr; + uint32_t num_last_entries; #ifdef H5C_DO_SANITY_CHECKS - int32_t slist_len_increase; - int64_t slist_size_increase; + int32_t slist_len_increase; + int64_t slist_size_increase; #endif /* H5C_DO_SANITY_CHECKS */ /* Fields for maintaining list of tagged entries */ - H5C_tag_info_t * tag_list; - bool ignore_tags; - uint32_t num_objs_corked; + H5C_tag_info_t *tag_list; + bool ignore_tags; + uint32_t num_objs_corked; /* Fields for tracking protected entries */ - uint32_t pl_len; - size_t pl_size; - H5C_cache_entry_t * pl_head_ptr; - H5C_cache_entry_t * pl_tail_ptr; + uint32_t pl_len; + size_t pl_size; + H5C_cache_entry_t *pl_head_ptr; + H5C_cache_entry_t *pl_tail_ptr; /* Fields for tracking pinned entries */ - uint32_t pel_len; - size_t pel_size; - H5C_cache_entry_t * pel_head_ptr; - H5C_cache_entry_t * pel_tail_ptr; + uint32_t pel_len; + size_t pel_size; + H5C_cache_entry_t *pel_head_ptr; + H5C_cache_entry_t *pel_tail_ptr; /* Fields for complete LRU list of entries */ - uint32_t LRU_list_len; - size_t LRU_list_size; - H5C_cache_entry_t * LRU_head_ptr; - H5C_cache_entry_t * LRU_tail_ptr; + uint32_t LRU_list_len; + size_t LRU_list_size; + H5C_cache_entry_t *LRU_head_ptr; + H5C_cache_entry_t *LRU_tail_ptr; #if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS /* Fields for clean LRU list of entries */ - uint32_t cLRU_list_len; - size_t cLRU_list_size; - H5C_cache_entry_t * cLRU_head_ptr; - H5C_cache_entry_t * cLRU_tail_ptr; + uint32_t cLRU_list_len; + size_t cLRU_list_size; + H5C_cache_entry_t *cLRU_head_ptr; + H5C_cache_entry_t *cLRU_tail_ptr; /* Fields for dirty LRU list of entries */ - uint32_t dLRU_list_len; - size_t dLRU_list_size; - H5C_cache_entry_t * dLRU_head_ptr; - H5C_cache_entry_t * dLRU_tail_ptr; + uint32_t dLRU_list_len; + size_t dLRU_list_size; + H5C_cache_entry_t *dLRU_head_ptr; + H5C_cache_entry_t *dLRU_tail_ptr; #endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ #ifdef H5_HAVE_PARALLEL /* Fields for collective metadata reads */ - uint32_t coll_list_len; - size_t coll_list_size; - H5C_cache_entry_t * coll_head_ptr; - H5C_cache_entry_t * coll_tail_ptr; + uint32_t coll_list_len; + size_t coll_list_size; + H5C_cache_entry_t *coll_head_ptr; + H5C_cache_entry_t *coll_tail_ptr; /* Fields for collective metadata writes */ - H5SL_t * coll_write_list; + H5SL_t *coll_write_list; #endif /* H5_HAVE_PARALLEL */ /* Fields for automatic cache size adjustment */ - bool size_increase_possible; - bool flash_size_increase_possible; + bool size_increase_possible; + bool flash_size_increase_possible; size_t flash_size_increase_threshold; - bool size_decrease_possible; - bool resize_enabled; - bool cache_full; - bool size_decreased; - bool resize_in_progress; - bool msic_in_progress; + bool size_decrease_possible; + bool resize_enabled; + bool cache_full; + bool size_decreased; + bool resize_in_progress; + bool msic_in_progress; H5C_auto_size_ctl_t resize_ctl; /* Fields for epoch markers used in automatic cache size adjustment */ - int32_t epoch_markers_active; - bool epoch_marker_active[H5C__MAX_EPOCH_MARKERS]; - int32_t epoch_marker_ringbuf[H5C__MAX_EPOCH_MARKERS+1]; - int32_t epoch_marker_ringbuf_first; - int32_t epoch_marker_ringbuf_last; - int32_t epoch_marker_ringbuf_size; - H5C_cache_entry_t epoch_markers[H5C__MAX_EPOCH_MARKERS]; + int32_t epoch_markers_active; + bool epoch_marker_active[H5C__MAX_EPOCH_MARKERS]; + int32_t epoch_marker_ringbuf[H5C__MAX_EPOCH_MARKERS + 1]; + int32_t epoch_marker_ringbuf_first; + int32_t epoch_marker_ringbuf_last; + int32_t epoch_marker_ringbuf_size; + H5C_cache_entry_t epoch_markers[H5C__MAX_EPOCH_MARKERS]; /* Fields for cache hit rate collection */ - int64_t cache_hits; - int64_t cache_accesses; + int64_t cache_hits; + int64_t cache_accesses; /* fields supporting generation of a cache image on file close */ H5C_cache_image_ctl_t image_ctl; - bool serialization_in_progress; - bool load_image; - bool image_loaded; - bool delete_image; - haddr_t image_addr; - hsize_t image_len; - hsize_t image_data_len; - int64_t entries_loaded_counter; - int64_t entries_inserted_counter; - int64_t entries_relocated_counter; - int64_t entry_fd_height_change_counter; - uint32_t num_entries_in_image; - H5C_image_entry_t * image_entries; - void * image_buffer; + bool serialization_in_progress; + bool load_image; + bool image_loaded; + bool delete_image; + haddr_t image_addr; + hsize_t image_len; + hsize_t image_data_len; + int64_t entries_loaded_counter; + int64_t entries_inserted_counter; + int64_t entries_relocated_counter; + int64_t entry_fd_height_change_counter; + uint32_t num_entries_in_image; + H5C_image_entry_t *image_entries; + void *image_buffer; /* Free Space Manager Related fields */ - bool rdfsm_settled; - bool mdfsm_settled; + bool rdfsm_settled; + bool mdfsm_settled; #if H5C_COLLECT_CACHE_STATS /* stats fields */ - int64_t hits[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t misses[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t write_protects[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t read_protects[H5C__MAX_NUM_TYPE_IDS + 1]; - int32_t max_read_protects[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t insertions[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t pinned_insertions[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t clears[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t flushes[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t evictions[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t take_ownerships[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t moves[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t entry_flush_moves[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t cache_flush_moves[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t pins[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t unpins[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t dirty_pins[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t pinned_flushes[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t pinned_clears[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t size_increases[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t size_decreases[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t entry_flush_size_changes[H5C__MAX_NUM_TYPE_IDS + 1]; - int64_t cache_flush_size_changes[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t hits[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t misses[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t write_protects[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t read_protects[H5C__MAX_NUM_TYPE_IDS + 1]; + int32_t max_read_protects[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t insertions[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t pinned_insertions[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t clears[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t flushes[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t evictions[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t take_ownerships[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t moves[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t entry_flush_moves[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t cache_flush_moves[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t pins[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t unpins[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t dirty_pins[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t pinned_flushes[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t pinned_clears[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t size_increases[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t size_decreases[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t entry_flush_size_changes[H5C__MAX_NUM_TYPE_IDS + 1]; + int64_t cache_flush_size_changes[H5C__MAX_NUM_TYPE_IDS + 1]; /* Fields for hash table operations */ - int64_t total_ht_insertions; - int64_t total_ht_deletions; - int64_t successful_ht_searches; - int64_t total_successful_ht_search_depth; - int64_t failed_ht_searches; - int64_t total_failed_ht_search_depth; - uint32_t max_index_len; - size_t max_index_size; - size_t max_clean_index_size; - size_t max_dirty_index_size; + int64_t total_ht_insertions; + int64_t total_ht_deletions; + int64_t successful_ht_searches; + int64_t total_successful_ht_search_depth; + int64_t failed_ht_searches; + int64_t total_failed_ht_search_depth; + uint32_t max_index_len; + size_t max_index_size; + size_t max_clean_index_size; + size_t max_dirty_index_size; /* Fields for in-order skip list */ - uint32_t max_slist_len; - size_t max_slist_size; + uint32_t max_slist_len; + size_t max_slist_size; /* Fields for protected entry list */ - uint32_t max_pl_len; - size_t max_pl_size; + uint32_t max_pl_len; + size_t max_pl_size; /* Fields for pinned entry list */ - uint32_t max_pel_len; - size_t max_pel_size; + uint32_t max_pel_len; + size_t max_pel_size; /* Fields for tracking 'make space in cache' (msic) operations */ - int64_t calls_to_msic; - int64_t total_entries_skipped_in_msic; - int64_t total_dirty_pf_entries_skipped_in_msic; - int64_t total_entries_scanned_in_msic; - int32_t max_entries_skipped_in_msic; - int32_t max_dirty_pf_entries_skipped_in_msic; - int32_t max_entries_scanned_in_msic; - int64_t entries_scanned_to_make_space; + int64_t calls_to_msic; + int64_t total_entries_skipped_in_msic; + int64_t total_dirty_pf_entries_skipped_in_msic; + int64_t total_entries_scanned_in_msic; + int32_t max_entries_skipped_in_msic; + int32_t max_dirty_pf_entries_skipped_in_msic; + int32_t max_entries_scanned_in_msic; + int64_t entries_scanned_to_make_space; /* Fields for tracking skip list scan restarts */ - int64_t slist_scan_restarts; - int64_t LRU_scan_restarts; - int64_t index_scan_restarts; + int64_t slist_scan_restarts; + int64_t LRU_scan_restarts; + int64_t index_scan_restarts; /* Fields for tracking cache image operations */ - int32_t images_created; - int32_t images_read; - int32_t images_loaded; - hsize_t last_image_size; + int32_t images_created; + int32_t images_read; + int32_t images_loaded; + hsize_t last_image_size; /* Fields for tracking prefetched entries */ - int64_t prefetches; - int64_t dirty_prefetches; - int64_t prefetch_hits; + int64_t prefetches; + int64_t dirty_prefetches; + int64_t prefetch_hits; #if H5C_COLLECT_CACHE_ENTRY_STATS - int32_t max_accesses[H5C__MAX_NUM_TYPE_IDS + 1]; - int32_t min_accesses[H5C__MAX_NUM_TYPE_IDS + 1]; - int32_t max_clears[H5C__MAX_NUM_TYPE_IDS + 1]; - int32_t max_flushes[H5C__MAX_NUM_TYPE_IDS + 1]; - size_t max_size[H5C__MAX_NUM_TYPE_IDS + 1]; - int32_t max_pins[H5C__MAX_NUM_TYPE_IDS + 1]; + int32_t max_accesses[H5C__MAX_NUM_TYPE_IDS + 1]; + int32_t min_accesses[H5C__MAX_NUM_TYPE_IDS + 1]; + int32_t max_clears[H5C__MAX_NUM_TYPE_IDS + 1]; + int32_t max_flushes[H5C__MAX_NUM_TYPE_IDS + 1]; + size_t max_size[H5C__MAX_NUM_TYPE_IDS + 1]; + int32_t max_pins[H5C__MAX_NUM_TYPE_IDS + 1]; #endif /* H5C_COLLECT_CACHE_ENTRY_STATS */ #endif /* H5C_COLLECT_CACHE_STATS */ - char prefix[H5C__PREFIX_LEN]; + char prefix[H5C__PREFIX_LEN]; #ifndef NDEBUG - int64_t get_entry_ptr_from_addr_counter; + int64_t get_entry_ptr_from_addr_counter; #endif }; /* H5C_t */ @@ -3235,12 +3100,10 @@ struct H5C_t { /* Define typedef for tagged cache entry iteration callbacks */ typedef int (*H5C_tag_iter_cb_t)(H5C_cache_entry_t *entry, void *ctx); - /*****************************/ /* Package Private Variables */ /*****************************/ - /******************************/ /* Package Private Prototypes */ /******************************/ @@ -3253,19 +3116,17 @@ H5_DLL herr_t H5C__autoadjust__ageout__remove_excess_markers(H5C_t *cache_ptr); H5_DLL herr_t H5C__flash_increase_cache_size(H5C_t *cache_ptr, size_t old_entry_size, size_t new_entry_size); H5_DLL herr_t H5C__flush_invalidate_cache(H5F_t *f, unsigned flags); H5_DLL herr_t H5C__flush_ring(H5F_t *f, H5C_ring_t ring, unsigned flags); -H5_DLL herr_t H5C__flush_single_entry(H5F_t *f, H5C_cache_entry_t *entry_ptr, - unsigned flags); +H5_DLL herr_t H5C__flush_single_entry(H5F_t *f, H5C_cache_entry_t *entry_ptr, unsigned flags); H5_DLL herr_t H5C__generate_cache_image(H5F_t *f, H5C_t *cache_ptr); H5_DLL herr_t H5C__load_cache_image(H5F_t *f); -H5_DLL herr_t H5C__make_space_in_cache(H5F_t * f, size_t space_needed, - bool write_permitted); +H5_DLL herr_t H5C__make_space_in_cache(H5F_t *f, size_t space_needed, bool write_permitted); H5_DLL herr_t H5C__serialize_cache(H5F_t *f); H5_DLL herr_t H5C__serialize_single_entry(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr); -H5_DLL herr_t H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, bool match_global, - H5C_tag_iter_cb_t cb, void *cb_ctx); +H5_DLL herr_t H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, bool match_global, H5C_tag_iter_cb_t cb, + void *cb_ctx); /* Routines for operating on entry tags */ -H5_DLL herr_t H5C__tag_entry(H5C_t * cache_ptr, H5C_cache_entry_t * entry_ptr); +H5_DLL herr_t H5C__tag_entry(H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr); H5_DLL herr_t H5C__untag_entry(H5C_t *cache, H5C_cache_entry_t *entry); /* Routines for operating on cache images */ @@ -3288,4 +3149,3 @@ H5_DLL herr_t H5C__verify_cork_tag_test(hid_t fid, H5O_token_t tag_token, bool s #endif /* H5C_TESTING */ #endif /* H5Cpkg_H */ -/* clang-format on */ 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/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/H5Ocache.c b/src/H5Ocache.c index 6916a9044c7..cc8033baf55 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() */ @@ -215,27 +224,17 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata) 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 (stored_chksum != computed_chksum) + ret_value = false; } else assert(!(udata->common.file_intent & H5F_ACC_SWMR_WRITE)); @@ -275,21 +274,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 */ @@ -1144,25 +1134,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 a98e22a1821..e7fcf0cd270 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -976,7 +976,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/H5T.c b/src/H5T.c index cec26a80e0c..dc531f85a70 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 */ /****************/ @@ -4471,30 +4482,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 * @@ -5516,7 +5503,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/H5Tconv_string.h b/src/H5Tconv_string.h new file mode 100644 index 00000000000..5a8a6354539 --- /dev/null +++ b/src/H5Tconv_string.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_string_H +#define H5Tconv_string_H + +/* Private headers needed by this file */ +#include "H5Tpkg.h" + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/****************************************/ +/* 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/H5private.h b/src/H5private.h index aa8c20537e4..148ac884072 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 /* @@ -1217,7 +1219,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 " \ @@ -1253,8 +1255,8 @@ 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"); \ } @@ -1263,7 +1265,7 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); 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; @@ -1412,7 +1414,6 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_ENTER_NOAPI_NOFS \ { \ FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ - \ { /* @@ -1517,13 +1518,13 @@ 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); \ } \ @@ -1534,8 +1535,8 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); ; \ } /*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); \ } \ @@ -1557,8 +1558,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); \ } \ diff --git a/src/Makefile.am b/src/Makefile.am index e6625777712..5e081a38275 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -92,6 +92,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/test/cmpd_dset.c b/test/cmpd_dset.c index f19f0c4c87e..c3998a39adf 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 b8888dfec5b..b6ff6342eb5 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -1117,11 +1117,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/tools/test/h5dump/CMakeTests.cmake b/tools/test/h5dump/CMakeTests.cmake index 2369f63c746..a4b43eee4e3 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 @@ -371,6 +373,7 @@ set (HDF5_ERROR_REFERENCE_TEST_FILES filter_fail.err non_existing.err + infinite_loop.err tall-1.err tall-2A.err tall-2A0.err @@ -1423,6 +1426,9 @@ # test for non-existing file ADD_H5_TEST (non_existing 1 --enable-error-stack tgroup.h5 non_existing.h5) + # test to verify github issue#3790: infinite loop closing library + ADD_H5_TEST (infinite_loop 1 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) diff --git a/tools/test/h5dump/errfiles/infinite_loop.err b/tools/test/h5dump/errfiles/infinite_loop.err new file mode 100644 index 00000000000..c89e1551d3b --- /dev/null +++ b/tools/test/h5dump/errfiles/infinite_loop.err @@ -0,0 +1 @@ +h5dump error: unable to open file "3790_infinite_loop.h5" diff --git a/tools/test/h5dump/errfiles/tall-1.err b/tools/test/h5dump/errfiles/tall-1.err index 84401596034..74ccb51f21a 100644 --- a/tools/test/h5dump/errfiles/tall-1.err +++ b/tools/test/h5dump/errfiles/tall-1.err @@ -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 H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object diff --git a/tools/test/h5dump/errfiles/tall-2A.err b/tools/test/h5dump/errfiles/tall-2A.err index 84401596034..74ccb51f21a 100644 --- a/tools/test/h5dump/errfiles/tall-2A.err +++ b/tools/test/h5dump/errfiles/tall-2A.err @@ -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 H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object diff --git a/tools/test/h5dump/errfiles/tall-2A0.err b/tools/test/h5dump/errfiles/tall-2A0.err index 84401596034..74ccb51f21a 100644 --- a/tools/test/h5dump/errfiles/tall-2A0.err +++ b/tools/test/h5dump/errfiles/tall-2A0.err @@ -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 H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object diff --git a/tools/test/h5dump/errfiles/tall-2B.err b/tools/test/h5dump/errfiles/tall-2B.err index 84401596034..74ccb51f21a 100644 --- a/tools/test/h5dump/errfiles/tall-2B.err +++ b/tools/test/h5dump/errfiles/tall-2B.err @@ -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 H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object diff --git a/tools/test/h5dump/errfiles/tarray1_big.err b/tools/test/h5dump/errfiles/tarray1_big.err index a20b0b7ae8d..dd6e1b40860 100644 --- a/tools/test/h5dump/errfiles/tarray1_big.err +++ b/tools/test/h5dump/errfiles/tarray1_big.err @@ -1,25 +1,25 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #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): +H5tools-DIAG: Error detected in HDF5:tools (version (number)): #000: (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 index 7625965c453..86db5943f3c 100644 --- a/tools/test/h5dump/errfiles/tattr-3.err +++ b/tools/test/h5dump/errfiles/tattr-3.err @@ -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 H5Aopen(): unable to synchronously open attribute major: Attribute minor: Unable to create file diff --git a/tools/test/h5dump/errfiles/tattrregR.err b/tools/test/h5dump/errfiles/tattrregR.err index fa2014a1cf0..0f4a88eb117 100644 --- a/tools/test/h5dump/errfiles/tattrregR.err +++ b/tools/test/h5dump/errfiles/tattrregR.err @@ -1,18 +1,18 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #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): +H5tools-DIAG: Error detected in HDF5:tools (version (number)): #000: (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 index 650df925421..8d8c9ee373c 100644 --- a/tools/test/h5dump/errfiles/tcomp-3.err +++ b/tools/test/h5dump/errfiles/tcomp-3.err @@ -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 H5Topen2(): unable to open named datatype synchronously major: Datatype minor: Can't open object diff --git a/tools/test/h5dump/errfiles/tdataregR.err b/tools/test/h5dump/errfiles/tdataregR.err index fa2014a1cf0..0f4a88eb117 100644 --- a/tools/test/h5dump/errfiles/tdataregR.err +++ b/tools/test/h5dump/errfiles/tdataregR.err @@ -1,18 +1,18 @@ -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): +HDF5-DIAG: Error detected in HDF5 (version (number)): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #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): +H5tools-DIAG: Error detected in HDF5:tools (version (number)): #000: (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 index 051c6775331..07080d229d6 100644 --- a/tools/test/h5dump/errfiles/tdset-2.err +++ b/tools/test/h5dump/errfiles/tdset-2.err @@ -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 H5Dopen2(): unable to synchronously open dataset major: Dataset minor: Can't open object @@ -29,7 +29,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5Lget_info2(): unable to get link info major: Links minor: Can't get value diff --git a/tools/test/h5dump/errfiles/textlink.err b/tools/test/h5dump/errfiles/textlink.err index 04b129c535b..bad1dd32d62 100644 --- a/tools/test/h5dump/errfiles/textlink.err +++ b/tools/test/h5dump/errfiles/textlink.err @@ -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 H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object @@ -35,7 +35,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object diff --git a/tools/test/h5dump/errfiles/textlinkfar.err b/tools/test/h5dump/errfiles/textlinkfar.err index e5b81ce4197..cfa2ef970c6 100644 --- a/tools/test/h5dump/errfiles/textlinkfar.err +++ b/tools/test/h5dump/errfiles/textlinkfar.err @@ -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 H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object @@ -59,7 +59,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5G_loc_find(): can't find object major: Symbol table minor: Object not found @@ -156,7 +156,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5G_loc_find(): can't find object major: Symbol table minor: Object not found diff --git a/tools/test/h5dump/errfiles/textlinksrc.err b/tools/test/h5dump/errfiles/textlinksrc.err index e5b81ce4197..cfa2ef970c6 100644 --- a/tools/test/h5dump/errfiles/textlinksrc.err +++ b/tools/test/h5dump/errfiles/textlinksrc.err @@ -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 H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object @@ -59,7 +59,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5G_loc_find(): can't find object major: Symbol table minor: Object not found @@ -156,7 +156,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5G_loc_find(): can't find object major: Symbol table minor: Object not found diff --git a/tools/test/h5dump/errfiles/tgroup-2.err b/tools/test/h5dump/errfiles/tgroup-2.err index f9fa0cfd08c..518bc695e06 100644 --- a/tools/test/h5dump/errfiles/tgroup-2.err +++ b/tools/test/h5dump/errfiles/tgroup-2.err @@ -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 H5Gopen2(): unable to synchronously open group major: Symbol table minor: Unable to create file diff --git a/tools/test/h5dump/errfiles/torderlinks1.err b/tools/test/h5dump/errfiles/torderlinks1.err index 182fc31a9a5..d715aa158b1 100644 --- a/tools/test/h5dump/errfiles/torderlinks1.err +++ b/tools/test/h5dump/errfiles/torderlinks1.err @@ -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 H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object diff --git a/tools/test/h5dump/errfiles/torderlinks2.err b/tools/test/h5dump/errfiles/torderlinks2.err index 182fc31a9a5..d715aa158b1 100644 --- a/tools/test/h5dump/errfiles/torderlinks2.err +++ b/tools/test/h5dump/errfiles/torderlinks2.err @@ -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 H5Oopen(): unable to synchronously open object major: Object header minor: Can't open object diff --git a/tools/test/h5dump/errfiles/tperror.err b/tools/test/h5dump/errfiles/tperror.err index 9e7972a8091..83757923dbb 100644 --- a/tools/test/h5dump/errfiles/tperror.err +++ b/tools/test/h5dump/errfiles/tperror.err @@ -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 H5Dopen2(): unable to synchronously open dataset major: Dataset minor: Can't open object @@ -29,7 +29,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5Lget_info2(): unable to get link info major: Links minor: Can't get value diff --git a/tools/test/h5dump/errfiles/tqmarkfile.err b/tools/test/h5dump/errfiles/tqmarkfile.err index 4c3b2efd580..aef14cb6d4b 100644 --- a/tools/test/h5dump/errfiles/tqmarkfile.err +++ b/tools/test/h5dump/errfiles/tqmarkfile.err @@ -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 H5Dopen2(): not found major: Dataset minor: Object not found @@ -14,7 +14,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #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): +HDF5-DIAG: Error detected in HDF5 (version (number)): #000: (file name) line (number) in H5Lget_info2(): unable to get link info major: Symbol table minor: Object not found diff --git a/tools/test/h5dump/errfiles/tslink-D.err b/tools/test/h5dump/errfiles/tslink-D.err index f465f290306..1c5cc23e8fb 100644 --- a/tools/test/h5dump/errfiles/tslink-D.err +++ b/tools/test/h5dump/errfiles/tslink-D.err @@ -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 H5Dopen2(): unable to synchronously open dataset major: Dataset minor: Can't open object 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 00000000000..0d3910a1a16 Binary files /dev/null and b/tools/test/h5dump/testfiles/3790_infinite_loop.h5 differ diff --git a/tools/test/h5dump/testh5dump.sh.in b/tools/test/h5dump/testh5dump.sh.in index 0964d7dda6d..007f93c07e3 100644 --- a/tools/test/h5dump/testh5dump.sh.in +++ b/tools/test/h5dump/testh5dump.sh.in @@ -138,6 +138,7 @@ $SRC_H5DUMP_TESTFILES/tfloat16_be.h5 $SRC_H5DUMP_TESTFILES/tfpformat.h5 $SRC_H5DUMP_TESTFILES/tfvalues.h5 $SRC_H5DUMP_TESTFILES/tgroup.h5 +$SRC_H5DUMP_TESTFILES/3790_infinite_loop.h5 $SRC_H5DUMP_TESTFILES/tgrp_comments.h5 $SRC_H5DUMP_TESTFILES/tgrpnullspace.h5 $SRC_H5DUMP_TESTFILES/thlink.h5 @@ -200,6 +201,7 @@ $SRC_H5DUMP_OUTFILES/charsets.ddl $SRC_H5DUMP_OUTFILES/file_space.ddl $SRC_H5DUMP_OUTFILES/filter_fail.ddl $SRC_H5DUMP_OUTFILES/non_existing.ddl +$SRC_H5DUMP_OUTFILES/infinite_loop.ddl $SRC_H5DUMP_OUTFILES/packedbits.ddl $SRC_H5DUMP_OUTFILES/tall-1.ddl $SRC_H5DUMP_OUTFILES/tall-2.ddl @@ -395,6 +397,7 @@ $SRC_H5DUMP_EXPFILES/twithddlfile.exp LIST_ERROR_TEST_FILES=" ${SRC_H5DUMP_ERRORFILES}/filter_fail.err ${SRC_H5DUMP_ERRORFILES}/non_existing.err +${SRC_H5DUMP_ERRORFILES}/infinite_loop.err ${SRC_H5DUMP_ERRORFILES}/tall-1.err ${SRC_H5DUMP_ERRORFILES}/tall-2A.err ${SRC_H5DUMP_ERRORFILES}/tall-2A0.err @@ -796,7 +799,7 @@ TOOLTEST3() { 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)/' \ @@ -854,7 +857,7 @@ TOOLTEST4() { 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)/' \ @@ -919,7 +922,7 @@ TOOLTEST5() { 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)/' \ @@ -1561,6 +1564,9 @@ TOOLTEST2 tall-6.exp --enable-error-stack -y -o tall-6.txt -d /g1/g1.1/dset1.1.1 # test for non-existing file TOOLTEST3 non_existing.ddl --enable-error-stack tgroup.h5 non_existing.h5 +# test to verify github issue #3790: infinite loop closing library +TOOLTEST4 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 diff --git a/tools/test/h5dump/testh5dumppbits.sh.in b/tools/test/h5dump/testh5dumppbits.sh.in index e90cc86e2ee..66ff231ed79 100644 --- a/tools/test/h5dump/testh5dumppbits.sh.in +++ b/tools/test/h5dump/testh5dumppbits.sh.in @@ -337,7 +337,7 @@ TOOLTEST3() { 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)/' \ @@ -394,7 +394,7 @@ TOOLTEST4() { 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)/' \ diff --git a/tools/test/h5dump/testh5dumpvds.sh.in b/tools/test/h5dump/testh5dumpvds.sh.in index 2bd38dc8a32..28727688bd0 100644 --- a/tools/test/h5dump/testh5dumpvds.sh.in +++ b/tools/test/h5dump/testh5dumpvds.sh.in @@ -318,7 +318,7 @@ TOOLTEST3() { 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)/' \ @@ -376,7 +376,7 @@ TOOLTEST4() { 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)/' \ diff --git a/tools/test/h5format_convert/testh5fc.sh.in b/tools/test/h5format_convert/testh5fc.sh.in index 756156ebb02..94516fb7066 100644 --- a/tools/test/h5format_convert/testh5fc.sh.in +++ b/tools/test/h5format_convert/testh5fc.sh.in @@ -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)/' \ 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)/' \