diff options
author | M. Scot Breitenfeld <brtnfld@hdfgroup.org> | 2019-06-25 17:39:35 (GMT) |
---|---|---|
committer | M. Scot Breitenfeld <brtnfld@hdfgroup.org> | 2019-06-25 17:39:35 (GMT) |
commit | 35c9af8371c4da7f5327c76ddab097b442128f59 (patch) | |
tree | d51be51c385a9b463388ba154efc3fa37cad49e8 /c++ | |
parent | c752332bfd0e9c3090f3a0c02d0253cd45c2e2ce (diff) | |
parent | 1d8f7bf297100ec11204442708a7f670a89f3f02 (diff) | |
download | hdf5-inactive/parallel_vds_develop.zip hdf5-inactive/parallel_vds_develop.tar.gz hdf5-inactive/parallel_vds_develop.tar.bz2 |
Merge branch 'develop' into parallel_vds_developinactive/parallel_vds_develop
Diffstat (limited to 'c++')
-rw-r--r-- | c++/Makefile.am | 14 | ||||
-rw-r--r-- | c++/examples/CMakeLists.txt | 22 | ||||
-rw-r--r-- | c++/examples/CMakeTests.cmake | 8 | ||||
-rw-r--r-- | c++/src/C2Cppfunction_map.htm | 36 | ||||
-rw-r--r-- | c++/src/CMakeLists.txt | 40 | ||||
-rw-r--r-- | c++/src/H5File.cpp | 21 | ||||
-rw-r--r-- | c++/src/H5File.h | 3 | ||||
-rw-r--r-- | c++/src/H5LaccProp.h | 11 | ||||
-rw-r--r-- | c++/src/H5LcreatProp.cpp | 40 | ||||
-rw-r--r-- | c++/src/H5LcreatProp.h | 19 | ||||
-rw-r--r-- | c++/src/H5Location.cpp | 7 | ||||
-rw-r--r-- | c++/src/H5Object.cpp | 73 | ||||
-rw-r--r-- | c++/src/H5Object.h | 26 | ||||
-rw-r--r-- | c++/src/cpp_doc_config | 2 | ||||
-rw-r--r-- | c++/test/CMakeLists.txt | 15 | ||||
-rw-r--r-- | c++/test/tarray.cpp | 3 | ||||
-rw-r--r-- | c++/test/tfile.cpp | 59 | ||||
-rw-r--r-- | c++/test/tlinks.cpp | 416 | ||||
-rw-r--r-- | c++/test/tobject.cpp | 128 |
19 files changed, 594 insertions, 349 deletions
diff --git a/c++/Makefile.am b/c++/Makefile.am index 94fbefc..319ce6e 100644 --- a/c++/Makefile.am +++ b/c++/Makefile.am @@ -18,9 +18,21 @@ include $(top_srcdir)/config/commence.am +if BUILD_TESTS_CONDITIONAL + TEST_DIR = test +else + TEST_DIR= +endif + ## Only recurse into subdirectories if C++ interface is enabled. if BUILD_CXX_CONDITIONAL - SUBDIRS=src test + SUBDIRS=src $(TEST_DIR) + +# Test with just the native connector, with a single pass-through connector +# and with a doubly-stacked pass-through. +VOL_LIST = native "pass_through under_vol=0;under_info={}" \ + "pass_through under_vol=505;under_info={under_vol=0;under_info={}}" + endif DIST_SUBDIRS = src test examples diff --git a/c++/examples/CMakeLists.txt b/c++/examples/CMakeLists.txt index d3a18f2..2088019 100644 --- a/c++/examples/CMakeLists.txt +++ b/c++/examples/CMakeLists.txt @@ -34,17 +34,27 @@ set (tutr_examples foreach (example ${examples}) add_executable (cpp_ex_${example} ${HDF5_CPP_EXAMPLES_SOURCE_DIR}/${example}.cpp) - target_include_directories(cpp_ex_${example} PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") - TARGET_C_PROPERTIES (cpp_ex_${example} STATIC) - target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIB_TARGET} ${HDF5_LIB_TARGET}) + target_include_directories (cpp_ex_${example} PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + if (NOT BUILD_SHARED_LIBS) + TARGET_C_PROPERTIES (cpp_ex_${example} STATIC) + target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIB_TARGET} ${HDF5_LIB_TARGET}) + else () + TARGET_C_PROPERTIES (cpp_ex_${example} SHARED) + target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) + endif () set_target_properties (cpp_ex_${example} PROPERTIES FOLDER examples/cpp) endforeach () foreach (example ${tutr_examples}) add_executable (cpp_ex_${example} ${HDF5_CPP_EXAMPLES_SOURCE_DIR}/${example}.cpp) - target_include_directories(cpp_ex_${example} PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") - TARGET_C_PROPERTIES (cpp_ex_${example} STATIC) - target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIB_TARGET} ${HDF5_LIB_TARGET}) + target_include_directories (cpp_ex_${example} PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + if (NOT BUILD_SHARED_LIBS) + TARGET_C_PROPERTIES (cpp_ex_${example} STATIC) + target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIB_TARGET} ${HDF5_LIB_TARGET}) + else () + TARGET_C_PROPERTIES (cpp_ex_${example} SHARED) + target_link_libraries (cpp_ex_${example} PRIVATE ${HDF5_CPP_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) + endif () set_target_properties (cpp_ex_${example} PROPERTIES FOLDER examples/cpp) endforeach () diff --git a/c++/examples/CMakeTests.cmake b/c++/examples/CMakeTests.cmake index bd1f95b..58bdb68 100644 --- a/c++/examples/CMakeTests.cmake +++ b/c++/examples/CMakeTests.cmake @@ -26,7 +26,7 @@ SDSextendible.h5 Select.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (CPP_ex-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "CPP_ex-clear-objects") @@ -46,7 +46,7 @@ -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (CPP_ex_${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "CPP_ex_${example}") @@ -66,7 +66,7 @@ h5tutr_groups.h5 h5tutr_subset.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (CPP_ex_tutr-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "CPP_ex_tutr-clear-objects") @@ -86,7 +86,7 @@ -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (CPP_ex_${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "CPP_ex_${example}") diff --git a/c++/src/C2Cppfunction_map.htm b/c++/src/C2Cppfunction_map.htm index b53ea15..2d779a3 100644 --- a/c++/src/C2Cppfunction_map.htm +++ b/c++/src/C2Cppfunction_map.htm @@ -7666,6 +7666,42 @@ normal'><span style='font-size:14.0pt;mso-bidi-font-size:11.0pt;line-height: normal'><o:p> </o:p></p> </td> </tr> + <tr style='mso-yfti-irow:180'> + <td width=263 style='width:197.2pt;border:solid windowtext 1.0pt;border-top: + none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt; + padding:0in 5.4pt 0in 5.4pt'> + <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height: + normal'>H5Fget_fileno</p> + </td> + <td width=474 valign=top style='width:355.2pt;border-top:none;border-left: + none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; + mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; + mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> + <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height: + normal'>unsigned long H5File::getFileNum()</p> + </td> + <td width=35 valign=top style='width:26.05pt;border-top:none;border-left: + none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; + mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; + mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> + <p class=MsoNormal align=center style='margin-bottom:0in;margin-bottom:.0001pt; + text-align:center;line-height:normal'><o:p> </o:p></p> + </td> + <td width=42 valign=top style='width:31.45pt;border-top:none;border-left: + none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; + mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; + mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> + <p class=MsoNormal align=center style='margin-bottom:0in;margin-bottom:.0001pt; + text-align:center;line-height:normal'><o:p> </o:p></p> + </td> + <td width=169 valign=top style='width:126.65pt;border-top:none;border-left: + none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; + mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; + mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> + <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height: + normal'><o:p> </o:p></p> + </td> + </tr> <tr style='mso-yfti-irow:181'> <td width=263 style='width:197.2pt;border:solid windowtext 1.0pt;border-top: none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt; diff --git a/c++/src/CMakeLists.txt b/c++/src/CMakeLists.txt index 945b352..8e7f8be 100644 --- a/c++/src/CMakeLists.txt +++ b/c++/src/CMakeLists.txt @@ -84,24 +84,26 @@ set (CPP_HDRS ${HDF5_CPP_SRC_SOURCE_DIR}/H5VarLenType.h ) -add_library (${HDF5_CPP_LIB_TARGET} STATIC ${CPP_SOURCES} ${CPP_HDRS}) -target_include_directories(${HDF5_CPP_LIB_TARGET} - PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>" - INTERFACE "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>" -) -target_compile_definitions(${HDF5_CPP_LIB_TARGET} - PRIVATE $<$<BOOL:${HDF5_ENABLE_PARALLEL}>:MPICH_SKIP_MPICXX;MPICH_IGNORE_CXX_SEEK># Parallel/MPI, prevent spurious cpp/cxx warnings -) -TARGET_C_PROPERTIES (${HDF5_CPP_LIB_TARGET} STATIC) -target_link_libraries (${HDF5_CPP_LIB_TARGET} PUBLIC ${HDF5_LIB_TARGET}) -set_global_variable (HDF5_LIBRARIES_TO_EXPORT "${HDF5_LIBRARIES_TO_EXPORT};${HDF5_CPP_LIB_TARGET}") -H5_SET_LIB_OPTIONS (${HDF5_CPP_LIB_TARGET} ${HDF5_CPP_LIB_NAME} STATIC 0) -set_target_properties (${HDF5_CPP_LIB_TARGET} PROPERTIES FOLDER libraries/cpp) -set (install_targets ${HDF5_CPP_LIB_TARGET}) +if (NOT ONLY_SHARED_LIBS) + add_library (${HDF5_CPP_LIB_TARGET} STATIC ${CPP_SOURCES} ${CPP_HDRS}) + target_include_directories (${HDF5_CPP_LIB_TARGET} + PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>" + INTERFACE "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>" + ) + target_compile_definitions(${HDF5_CPP_LIB_TARGET} + PRIVATE $<$<BOOL:${HDF5_ENABLE_PARALLEL}>:MPICH_SKIP_MPICXX;MPICH_IGNORE_CXX_SEEK># Parallel/MPI, prevent spurious cpp/cxx warnings + ) + TARGET_C_PROPERTIES (${HDF5_CPP_LIB_TARGET} STATIC) + target_link_libraries (${HDF5_CPP_LIB_TARGET} PUBLIC ${HDF5_LIB_TARGET}) + set_global_variable (HDF5_LIBRARIES_TO_EXPORT "${HDF5_LIBRARIES_TO_EXPORT};${HDF5_CPP_LIB_TARGET}") + H5_SET_LIB_OPTIONS (${HDF5_CPP_LIB_TARGET} ${HDF5_CPP_LIB_NAME} STATIC 0) + set_target_properties (${HDF5_CPP_LIB_TARGET} PROPERTIES FOLDER libraries/cpp) + set (install_targets ${HDF5_CPP_LIB_TARGET}) +endif () if (BUILD_SHARED_LIBS) add_library (${HDF5_CPP_LIBSH_TARGET} SHARED ${CPP_SOURCES} ${CPP_HDRS}) - target_include_directories(${HDF5_CPP_LIBSH_TARGET} + target_include_directories (${HDF5_CPP_LIBSH_TARGET} PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>" INTERFACE "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>" ) @@ -136,7 +138,9 @@ if (HDF5_EXPORTED_TARGETS) if (BUILD_SHARED_LIBS) INSTALL_TARGET_PDB (${HDF5_CPP_LIBSH_TARGET} ${HDF5_INSTALL_BIN_DIR} cpplibraries) endif () - INSTALL_TARGET_PDB (${HDF5_CPP_LIB_TARGET} ${HDF5_INSTALL_BIN_DIR} cpplibraries) + if (NOT ONLY_SHARED_LIBS) + INSTALL_TARGET_PDB (${HDF5_CPP_LIB_TARGET} ${HDF5_INSTALL_BIN_DIR} cpplibraries) + endif () install ( TARGETS @@ -163,7 +167,9 @@ set (_PKG_CONFIG_VERSION "${HDF5_PACKAGE_VERSION}") set (_PKG_CONFIG_LIBS_PRIVATE) -set (_PKG_CONFIG_LIBS "${_PKG_CONFIG_LIBS} -l${HDF5_CPP_LIB_CORENAME}") +if (NOT ONLY_SHARED_LIBS) + set (_PKG_CONFIG_LIBS "${_PKG_CONFIG_LIBS} -l${HDF5_CPP_LIB_CORENAME}") +endif () if (BUILD_SHARED_LIBS) set (_PKG_CONFIG_SH_LIBS "${_PKG_CONFIG_SH_LIBS} -l${HDF5_CPP_LIB_CORENAME}") endif () diff --git a/c++/src/H5File.cpp b/c++/src/H5File.cpp index 719c1ba..b9ecded 100644 --- a/c++/src/H5File.cpp +++ b/c++/src/H5File.cpp @@ -580,6 +580,27 @@ hsize_t H5File::getFileSize() const } //-------------------------------------------------------------------------- +// Function: H5File::getFileNum +///\brief Returns the file number of the HDF5 file. +///\return File number +///\exception H5::FileIException +///\par Description +/// This function is called after an existing file is opened in +/// order to retrieve the unique 'file number' for the file. +// Programmer Quincey Koziol - April 13, 2019 +//-------------------------------------------------------------------------- +unsigned long H5File::getFileNum() const +{ + unsigned long fileno = 0; + herr_t ret_value = H5Fget_fileno(id, &fileno); + if (ret_value < 0) + { + throw FileIException("H5File::getFileNum", "H5Fget_fileno failed"); + } + return (fileno); +} + +//-------------------------------------------------------------------------- // Function: H5File::getId ///\brief Get the id of this file ///\return File identifier diff --git a/c++/src/H5File.h b/c++/src/H5File.h index 332685e..1b1227f 100644 --- a/c++/src/H5File.h +++ b/c++/src/H5File.h @@ -69,6 +69,9 @@ class H5_DLLCPP H5File : public Group { // Returns the file size of the HDF5 file. hsize_t getFileSize() const; + // Returns the 'file number' of the HDF5 file. + unsigned long getFileNum() const; + // Determines if a file, specified by its name, is in HDF5 format static bool isHdf5(const char* name); static bool isHdf5(const H5std_string& name); diff --git a/c++/src/H5LaccProp.h b/c++/src/H5LaccProp.h index 70890b3..ec5e54f 100644 --- a/c++/src/H5LaccProp.h +++ b/c++/src/H5LaccProp.h @@ -12,9 +12,6 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -// Class LinkAccPropList represents the HDF5 file access property list and -// inherits from DataType. - #ifndef __H5LinkAccPropList_H #define __H5LinkAccPropList_H @@ -22,15 +19,15 @@ namespace H5 { /*! \class LinkAccPropList \brief Class LinkAccPropList inherits from PropList and provides - wrappers for the HDF5 file access property list. + wrappers for the HDF5 link access property list. */ // Inheritance: PropList -> IdComponent class H5_DLLCPP LinkAccPropList : public PropList { public: - ///\brief Default file access property list. + ///\brief Default link access property list. static const LinkAccPropList& DEFAULT; - // Creates a file access property list. + // Creates a link access property list. LinkAccPropList(); ///\brief Returns this class name. @@ -39,7 +36,7 @@ class H5_DLLCPP LinkAccPropList : public PropList { // Copy constructor: same as the original LinkAccPropList. LinkAccPropList(const LinkAccPropList& original); - // Creates a copy of an existing file access property list + // Creates a copy of an existing link access property list // using the property list id. LinkAccPropList (const hid_t plist_id); diff --git a/c++/src/H5LcreatProp.cpp b/c++/src/H5LcreatProp.cpp index 695c1fe..bde9339 100644 --- a/c++/src/H5LcreatProp.cpp +++ b/c++/src/H5LcreatProp.cpp @@ -103,6 +103,46 @@ LinkCreatPropList::LinkCreatPropList(const LinkCreatPropList& original) : PropLi LinkCreatPropList::LinkCreatPropList(const hid_t plist_id) : PropList(plist_id) {} //-------------------------------------------------------------------------- +// Function: LinkCreatPropList::setCreateIntermediateGroup +///\brief Specifies in property list whether to create missing +/// intermediate groups. +///\param crt_intmd_group - IN: Flag specifying whether to create +/// intermediate groups upon the creation of an object +///\exception H5::PropListIException +// April, 2019 +//-------------------------------------------------------------------------- +void LinkCreatPropList::setCreateIntermediateGroup(bool crt_intmd_group) const +{ + herr_t ret_value = H5Pset_create_intermediate_group(id, (unsigned)crt_intmd_group); + // Throw exception if H5Pset_create_intermediate_group returns failure + if (ret_value < 0) + { + throw PropListIException("setCreateIntermediateGroup", "H5Pset_create_intermediate_group failed"); + } +} + +//-------------------------------------------------------------------------- +// Function: LinkCreatPropList::getCreateIntermediateGroup +///\brief Determines whether property is set to enable creating missing +/// intermediate groups. +///\return true if creating intermediate groups is enabled, and false, otherwise +///\exception H5::PropListIException +// April, 2019 +//-------------------------------------------------------------------------- +bool LinkCreatPropList::getCreateIntermediateGroup() const +{ + unsigned crt_intmd_group; + herr_t ret_value = H5Pget_create_intermediate_group(id, &crt_intmd_group); + // Throw exception if H5Pget_create_intermediate_group returns failure + if (ret_value < 0) + { + throw PropListIException("getCreateIntermediateGroup", "H5Pget_create_intermediate_group failed"); + } + + return((bool)crt_intmd_group); +} + +//-------------------------------------------------------------------------- // Function: LinkCreatPropList::setCharEncoding ///\brief Sets the character encoding of the string. /// diff --git a/c++/src/H5LcreatProp.h b/c++/src/H5LcreatProp.h index 12cb479..908ef63 100644 --- a/c++/src/H5LcreatProp.h +++ b/c++/src/H5LcreatProp.h @@ -12,9 +12,6 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -// Class LinkCreatPropList represents the HDF5 file access property list and -// inherits from DataType. - #ifndef __H5LinkCreatPropList_H #define __H5LinkCreatPropList_H @@ -22,15 +19,15 @@ namespace H5 { /*! \class LinkCreatPropList \brief Class LinkCreatPropList inherits from PropList and provides - wrappers for the HDF5 file access property list. + wrappers for the HDF5 link creation property list. */ // Inheritance: PropList -> IdComponent class H5_DLLCPP LinkCreatPropList : public PropList { public: - ///\brief Default file access property list. + ///\brief Default link creation property list. static const LinkCreatPropList& DEFAULT; - // Creates a file access property list. + // Creates a link creation property list. LinkCreatPropList(); ///\brief Returns this class name. @@ -39,10 +36,18 @@ class H5_DLLCPP LinkCreatPropList : public PropList { // Copy constructor: same as the original LinkCreatPropList. LinkCreatPropList(const LinkCreatPropList& original); - // Creates a copy of an existing file access property list + // Creates a copy of an existing link creation property list // using the property list id. LinkCreatPropList (const hid_t plist_id); + // Specifies in property list whether to create missing + // intermediate groups + void setCreateIntermediateGroup(bool crt_intmd_group) const; + + // Determines whether property is set to enable creating missing + // intermediate groups + bool getCreateIntermediateGroup() const; + // Sets the character encoding of the string. void setCharEncoding(H5T_cset_t encoding) const; diff --git a/c++/src/H5Location.cpp b/c++/src/H5Location.cpp index 2c49016..2641960 100644 --- a/c++/src/H5Location.cpp +++ b/c++/src/H5Location.cpp @@ -1066,7 +1066,7 @@ void H5Location::link(const char *curr_name, const Group& new_loc, hid_t lcpl_id = lcpl.getId(); hid_t lapl_id = lapl.getId(); - ret_value = H5Lcreate_hard(getId(), curr_name, new_loc.getId(), new_name, H5P_DEFAULT, H5P_DEFAULT); + ret_value = H5Lcreate_hard(getId(), curr_name, new_loc_id, new_name, lcpl_id, lapl_id); if (ret_value < 0) throwException("link", "creating link failed"); } @@ -1102,14 +1102,13 @@ void H5Location::link(const H5std_string& curr_name, const Group& new_loc, /// H5Lcreate_hard APIs in the HDF5 C Reference Manual. // March 2018 //-------------------------------------------------------------------------- -void H5Location::link(const char *curr_name, const hid_t same_loc, - const char *new_name, const LinkCreatPropList& lcpl, const LinkAccPropList& lapl) const +void H5Location::link(const char *curr_name, const hid_t same_loc, const char *new_name, const LinkCreatPropList& lcpl, const LinkAccPropList& lapl) const { herr_t ret_value = -1; hid_t lcpl_id = lcpl.getId(); hid_t lapl_id = lapl.getId(); - ret_value = H5Lcreate_hard(getId(), curr_name, same_loc, new_name, H5P_DEFAULT, H5P_DEFAULT); + ret_value = H5Lcreate_hard(getId(), curr_name, same_loc, new_name, lcpl_id, lapl_id); if (ret_value < 0) throwException("link", "creating link failed"); diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp index 1c22efe..8d3334b 100644 --- a/c++/src/H5Object.cpp +++ b/c++/src/H5Object.cpp @@ -40,9 +40,8 @@ namespace H5 { #ifndef DOXYGEN_SHOULD_SKIP_THIS -// userAttrOpWrpr simply interfaces between the user's function and the -// C library function H5Aiterate2; used to resolve the different prototype -// problem. May be moved to Iterator later. +// userAttrOpWrpr interfaces between the user's function and the +// C library function H5Aiterate2 extern "C" herr_t userAttrOpWrpr(hid_t loc_id, const char *attr_name, const H5A_info_t *ainfo, void *op_data) { @@ -52,6 +51,17 @@ extern "C" herr_t userAttrOpWrpr(hid_t loc_id, const char *attr_name, return 0; } +// userVisitOpWrpr interfaces between the user's function and the +// C library function H5Ovisit2 +extern "C" herr_t userVisitOpWrpr(hid_t obj_id, const char *attr_name, + const H5O_info_t *obj_info, void *op_data) +{ + H5std_string s_attr_name = H5std_string(attr_name); + UserData4Visit* myData = reinterpret_cast<UserData4Visit *> (op_data); + int status = myData->op(*myData->obj, s_attr_name, obj_info, myData->opData); + return status; +} + //-------------------------------------------------------------------------- // Function: H5Object default constructor (protected) // Programmer Binh-Minh Ribler - 2000 @@ -197,8 +207,6 @@ Attribute H5Object::openAttribute(const unsigned int idx) const ///\par Description /// The signature of user_op is /// void (*)(H5::H5Location&, H5std_string, void*). -/// For information, please refer to the H5Aiterate2 API in -/// the HDF5 C Reference Manual. // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- int H5Object::iterateAttrs(attr_operator_t user_op, unsigned *_idx, void *op_data) @@ -228,6 +236,61 @@ int H5Object::iterateAttrs(attr_operator_t user_op, unsigned *_idx, void *op_dat } //-------------------------------------------------------------------------- +// Function: H5Object::visit +///\brief Recursively visits all HDF5 objects accessible from this object. +///\param idx_type - IN: Type of index; valid values include: +/// \li \c H5_INDEX_NAME +/// \li \c H5_INDEX_CRT_ORDER +///\param order - IN: Order in which index is traversed; valid values include: +/// \li \c H5_ITER_DEC +/// \li \c H5_ITER_INC +/// \li \c H5_ITER_NATIVE +///\param user_op - IN: Callback function passing data regarding the +/// object to the calling application +///\param *op_data - IN: User-defined pointer to data required by the +/// application for its processing of the object +///\param fields - IN: Flags specifying the fields to be retrieved +/// to the callback op via the H5O_info_t argument. +/// \li \c H5O_INFO_BASIC fileno, addr, type, and rc fields +/// \li \c H5O_INFO_TIME atime, mtime, ctime, and btime fields +/// \li \c H5O_INFO_NUM_ATTRS num_attrs field +/// \li \c H5O_INFO_HDR hdr field +/// \li \c H5O_INFO_META_SIZE meta_size field +/// \li \c H5O_INFO_ALL H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS | H5O_INFO_HDR | H5O_INFO_META_SIZE +///\return +/// \li On success: +/// \li the return value of the first operator that returns a positive value +/// \li zero if all members were processed with no operator returning non-zero +/// \li On failure: +/// \li an exception Exception will be thrown if something went +/// wrong within the library or the operator failed +///\exception H5::Exception +///\par Description +/// For information, please refer to the H5Ovisit2 API in the HDF5 +/// C Reference Manual. +// Programmer Binh-Minh Ribler - Feb, 2019 +//-------------------------------------------------------------------------- +void H5Object::visit(H5_index_t idx_type, H5_iter_order_t order, visit_operator_t user_op, void *op_data, unsigned int fields) +{ + // Store the user's function and data + UserData4Visit* userData = new UserData4Visit; + userData->opData = op_data; + userData->op = user_op; + userData->obj = this; + + // Call the C API passing in op wrapper and info + herr_t ret_value = H5Ovisit2(getId(), idx_type, order, userVisitOpWrpr, static_cast<void *>(userData), fields); + + // Release memory + delete userData; + + // Throw exception if H5Ovisit2 failed, which could be a failure in + // the library or in the call back operator + if (ret_value < 0) + throw Exception(inMemFunc("visit"), "H5Ovisit2 failed"); +} + +//-------------------------------------------------------------------------- // Function: H5Object::objVersion ///\brief Returns the header version of this HDF5 object. ///\return Object version, which can have the following values: diff --git a/c++/src/H5Object.h b/c++/src/H5Object.h index 10b3865..4a4e909 100644 --- a/c++/src/H5Object.h +++ b/c++/src/H5Object.h @@ -40,16 +40,30 @@ namespace H5 { // Inheritance: H5Location -> IdComponent // Define the operator function pointer for H5Aiterate(). -typedef void (*attr_operator_t)(H5Object& loc/*in*/, - const H5std_string attr_name/*in*/, - void *operator_data/*in,out*/); +typedef void (*attr_operator_t)(H5Object& loc, + const H5std_string attr_name, + void *operator_data); + +// Define the operator function pointer for H5Ovisit2(). +typedef int (*visit_operator_t)(H5Object& obj, + const H5std_string attr_name, + const H5O_info_t *oinfo, + void *operator_data); // User data for attribute iteration class UserData4Aiterate { public: attr_operator_t op; void* opData; - H5Object* location; + H5Object* location; // Consider changing to H5Location +}; + +// User data for visit iteration +class UserData4Visit { + public: + visit_operator_t op; + void* opData; + H5Object* obj; }; class H5_DLLCPP H5Object : public H5Location { @@ -71,6 +85,9 @@ class H5_DLLCPP H5Object : public H5Location { // Iterate user's function over the attributes of this object. int iterateAttrs(attr_operator_t user_op, unsigned* idx = NULL, void* op_data = NULL); + // Recursively visit elements reachable from this object. + void visit(H5_index_t idx_type, H5_iter_order_t order, visit_operator_t user_op, void *op_data, unsigned int fields); + // Returns the object header version of an object unsigned objVersion() const; @@ -98,6 +115,7 @@ class H5_DLLCPP H5Object : public H5Location { ssize_t getObjName(H5std_string& obj_name, size_t len = 0) const; H5std_string getObjName() const; + #ifndef DOXYGEN_SHOULD_SKIP_THIS protected: diff --git a/c++/src/cpp_doc_config b/c++/src/cpp_doc_config index 697fb77..14ca90c 100644 --- a/c++/src/cpp_doc_config +++ b/c++/src/cpp_doc_config @@ -38,7 +38,7 @@ PROJECT_NAME = # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "1.11.4" +PROJECT_NUMBER = "1.11.6" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/c++/test/CMakeLists.txt b/c++/test/CMakeLists.txt index 8e2d685..95ca9b1 100644 --- a/c++/test/CMakeLists.txt +++ b/c++/test/CMakeLists.txt @@ -38,16 +38,17 @@ set (srcdir ${CMAKE_CURRENT_SOURCE_DIR}) configure_file (${HDF5_CPP_TEST_SOURCE_DIR}/H5srcdir_str.h.in H5srcdir_str.h @ONLY) add_executable (cpp_testhdf5 ${CPP_TEST_SOURCES} ) -target_include_directories(cpp_testhdf5 PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};${HDF5_TEST_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") +target_include_directories (cpp_testhdf5 PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};${HDF5_TEST_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") target_compile_definitions(cpp_testhdf5 PRIVATE $<$<BOOL:${HDF5_ENABLE_PARALLEL}>:MPICH_SKIP_MPICXX;MPICH_IGNORE_CXX_SEEK># Parallel/MPI, prevent spurious cpp/cxx warnings ) -TARGET_C_PROPERTIES (cpp_testhdf5 STATIC) -target_link_libraries (cpp_testhdf5 PRIVATE - ${HDF5_CPP_LIB_TARGET} - ${HDF5_LIB_TARGET} - ${HDF5_TEST_LIB_TARGET} -) +if (NOT BUILD_SHARED_LIBS) + TARGET_C_PROPERTIES (cpp_testhdf5 STATIC) + target_link_libraries (cpp_testhdf5 PRIVATE ${HDF5_CPP_LIB_TARGET} ${HDF5_LIB_TARGET} ${HDF5_TEST_LIB_TARGET}) +else () + TARGET_C_PROPERTIES (cpp_testhdf5 SHARED) + target_link_libraries (cpp_testhdf5 PRIVATE ${HDF5_CPP_LIBSH_TARGET} ${HDF5_LIBSH_TARGET} ${HDF5_TEST_LIBSH_TARGET}) +endif () set_target_properties (cpp_testhdf5 PROPERTIES FOLDER test/cpp) include (CMakeTests.cmake) diff --git a/c++/test/tarray.cpp b/c++/test/tarray.cpp index 6bd4ca6..fccc556 100644 --- a/c++/test/tarray.cpp +++ b/c++/test/tarray.cpp @@ -286,7 +286,7 @@ H5::DataType getArr() *dims = 5; H5::ArrayType ret; ret = H5::ArrayType(H5::PredType::NATIVE_INT, 1, dims); - delete[] dims; + delete dims; return ret; } @@ -371,7 +371,6 @@ static void test_array_info() s1_t rdata[SPACE1_DIM1][ARRAY1_DIM1]; // Information read in hsize_t sdims1[] = {SPACE1_DIM1}; hsize_t tdims1[] = {ARRAY1_DIM1}; - int nmemb; // Number of compound members int ii; // counting variables hsize_t idxi, idxj, idxk; // dimension indicing variables H5T_class_t mclass; // Datatype class for field diff --git a/c++/test/tfile.cpp b/c++/test/tfile.cpp index a2bf1c2..055cf23 100644 --- a/c++/test/tfile.cpp +++ b/c++/test/tfile.cpp @@ -412,6 +412,64 @@ static void test_file_size() /*------------------------------------------------------------------------- + * Function: test_file_num + * + * Purpose Test file number. + * + * Return None + * + * Programmer Quincey Koziol + * April, 2019 + *------------------------------------------------------------------------- + */ +static void test_file_num() +{ + // Output message about test being performed + SUBTEST("File Number"); + + hid_t fapl_id; + fapl_id = h5_fileaccess(); // in h5test.c, returns a file access template + + try { + // Use the file access template id to create a file access prop. + // list object to pass in H5File::H5File + FileAccPropList fapl(fapl_id); + + // Create two files + H5File file1(FILE1, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl); + H5File file2(FILE2, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl); + + // Open the first file again + H5File file3(FILE1, H5F_ACC_RDWR); + + // Get file numbers + unsigned long file_num1 = file1.getFileNum(); + unsigned long file_num2 = file2.getFileNum(); + unsigned long file_num3 = file3.getFileNum(); + + // Check file numbers + if (file_num1 == file_num2) + issue_fail_msg("test_file_num()", __LINE__, __FILE__, "getFileNum() returned wrong value"); + if (file_num1 != file_num3) + issue_fail_msg("test_file_num()", __LINE__, __FILE__, "getFileNum() returned wrong value"); + + PASSED(); + } // end of try block + + catch (Exception& E) + { + issue_fail_msg("test_file_num()", __LINE__, __FILE__, E.getCDetailMsg()); + } + + // use C test utility routine to close property list. + herr_t ret = H5Pclose(fapl_id); + if (ret < 0) + issue_fail_msg("test_file_num()", __LINE__, __FILE__, "H5Pclose failed"); + +} // test_file_num() + + +/*------------------------------------------------------------------------- * Function: test_file_name * * Purpose Test getting file's name. @@ -966,6 +1024,7 @@ void test_file() test_file_create(); // Test file creation (also creation templates) test_file_open(); // Test file opening test_file_size(); // Test file size + test_file_num(); // Test file number test_file_name(); // Test getting file's name test_file_attribute(); // Test file attribute feature test_libver_bounds(); // Test format version diff --git a/c++/test/tlinks.cpp b/c++/test/tlinks.cpp index 6e990c9..491cd6a 100644 --- a/c++/test/tlinks.cpp +++ b/c++/test/tlinks.cpp @@ -31,288 +31,27 @@ using namespace H5; #include "h5test.h" #include "h5cpputil.h" // C++ utilility header file -// A lot of the definition inherited from C test links.c is left here until -// the H5L API is implemented and tests are completed - BMR 10/19/2009 -/* - * This file needs to access private information from the H5G package. - * This file also needs to access the group testing code. - */ -//#define H5G_FRIEND -//#define H5G_TESTING - -//#include "h5test.h" -//#include "H5Gpkg.h" /* Groups */ -//#include "H5Iprivate.h" /* IDs */ -//#include "H5Lprivate.h" /* Links */ - -/* File for external link test. Created with gen_udlinks.c */ -#define LINKED_FILE "be_extlink2.h5" - -#if 0 -const char *FILENAME[] = { - "links0", - "links1", - "links2", - "links3", - "links4a", /* 4 */ - "links4b", /* 5 */ - "links4c", /* 6 */ - "links4d", /* 7 */ - "links5", /* 8 */ - "links6", /* 9 */ - "links7", /* 10 */ - "links8", /* 11 */ - "extlinks0", /* 12: main files */ - "tmp/extlinks0", /* 13: */ - "extlinks1", /* 14: target files */ - "tmp/extlinks1", /* 15: */ - "extlinks2", /* 16: */ - "tmp/extlinks2", /* 17: */ - "extlinks3", /* 18: */ - "tmp/extlinks3", /* 19: */ - "extlinks4", /* 20: */ - "tmp/extlinks4", /* 21: */ - "extlinks5", /* 22: */ - "tmp/extlinks6", /* 23: */ - "extlinks7", /* 24: */ - "tmp/extlinks7", /* 25: */ - "tmp/extlinks8", /* 26: */ - "extlinks9", /* 27: */ - "tmp/extlinks9", /* 28: */ - "extlinks10", /* 29: */ /* TESTS for windows */ - "tmp/extlinks10", /* 30: */ - "tmp/extlinks11", /* 31: */ - "tmp/extlinks12", /* 32: */ - "extlinks13", /* 33: */ - "tmp/extlinks13", /* 34: */ - "tmp/extlinks14", /* 35: */ - "tmp/extlinks15", /* 36: */ - "extlinks16A", /* 37: */ /* TESTS for H5P_set_elink_fapl */ - "extlinks16B", /* 38: */ - "extlinks17", /* 39: */ - "extlinks18A", /* 40: */ - "extlinks18B", /* 41: */ - "extlinks19A", /* 42: */ - "extlinks19B", /* 43: */ - "extlinks20", /* 44: */ - NULL -}; - -#endif // 0 - -#define TMPDIR "tmp" - -#define FAMILY_SIZE 1024 -#define CORE_INCREMENT 1024 -#define NUM400 400 - -/* do not do check_all_closed() for "ext*" files and "tmp/ext*" */ -#define EXTSTOP 12 - -#define LINK_BUF_SIZE 1024 #define NAME_BUF_SIZE 1024 -#define MAX_NAME_LEN ((64*1024)+1024) - -/* Link type IDs */ -#define UD_HARD_TYPE 201 -#define UD_CB_TYPE H5L_TYPE_MAX -#define UD_PLIST_TYPE 128 -#define UD_CBFAIL_TYPE UD_PLIST_TYPE -#define UD_ERROR_TYPE 189 -#define UD_BAD_TYPE1 H5L_TYPE_HARD -#define UD_BAD_TYPE2 (H5L_TYPE_UD_MIN - 5) -#define UD_BAD_VERS (H5L_LINK_CLASS_T_VERS + 1) - -#define DEST_PROP_NAME "destination_group" -#define REREG_TARGET_NAME "rereg_target" - -#define UD_CB_LINK_NAME "ud_callback_link" -#define NEW_UD_CB_LINK_NAME "ud_callback_link2" -#define UD_CB_TARGET "ud_target" -#define UD_CB_TARGET_LEN 10 - -#define LE_FILENAME "le_extlink1.h5" -#define BE_FILENAME "be_extlink1.h5" - -#define ELINK_CB_FAM_SIZE (hsize_t) 100 - #define H5L_DIM1 100 #define H5L_DIM2 100 -/* Creation order macros */ -#define CORDER_SOFT_GROUP_NAME "corder_soft_group" -#define CORDER_NLINKS 18 - -/* Timestamp macros */ -#define TIMESTAMP_GROUP_1 "timestamp1" -#define TIMESTAMP_GROUP_2 "timestamp2" - -/* Link iteration struct */ -typedef struct { - H5_iter_order_t order; /* Direction of iteration */ - unsigned ncalled; /* # of times callback is entered */ - unsigned nskipped; /* # of links skipped */ - int stop; /* # of iterations to stop after */ - int64_t curr; /* Current creation order value */ - size_t max_visit; /* Size of "visited link" flag array */ - hbool_t *visited; /* Pointer to array of "visited link" flags */ -} link_iter_info_t; - -#if 0 -/* Link visit structs */ -typedef struct { - const char *path; /* Path to link */ - H5L_type_t type; /* Type of link */ -} link_visit_t; -static const link_visit_t lvisit0[] = { - {"Dataset_zero", H5L_TYPE_HARD}, - {"Group1", H5L_TYPE_HARD}, - {"Group1/Dataset_one", H5L_TYPE_HARD}, - {"Group1/Group2", H5L_TYPE_HARD}, - {"Group1/Group2/Dataset_two", H5L_TYPE_HARD}, - {"Group1/Group2/Type_two", H5L_TYPE_HARD}, - {"Group1/Group2/hard_zero", H5L_TYPE_HARD}, - {"Group1/Type_one", H5L_TYPE_HARD}, - {"Group1/hard_one", H5L_TYPE_HARD}, - {"Type_zero", H5L_TYPE_HARD}, - {"ext_dangle", H5L_TYPE_EXTERNAL}, - {"ext_one", H5L_TYPE_EXTERNAL}, - {"hard_one", H5L_TYPE_HARD}, - {"hard_two", H5L_TYPE_HARD}, - {"hard_zero", H5L_TYPE_HARD}, - {"soft_dangle", H5L_TYPE_SOFT}, - {"soft_one", H5L_TYPE_SOFT}, - {"soft_two", H5L_TYPE_SOFT} -}; -static const link_visit_t lvisit1[] = { - {"Dataset_one", H5L_TYPE_HARD}, - {"Group2", H5L_TYPE_HARD}, - {"Group2/Dataset_two", H5L_TYPE_HARD}, - {"Group2/Type_two", H5L_TYPE_HARD}, - {"Group2/hard_zero", H5L_TYPE_HARD}, - {"Group2/hard_zero/Dataset_zero", H5L_TYPE_HARD}, - {"Group2/hard_zero/Group1", H5L_TYPE_HARD}, - {"Group2/hard_zero/Type_zero", H5L_TYPE_HARD}, - {"Group2/hard_zero/ext_dangle", H5L_TYPE_EXTERNAL}, - {"Group2/hard_zero/ext_one", H5L_TYPE_EXTERNAL}, - {"Group2/hard_zero/hard_one", H5L_TYPE_HARD}, - {"Group2/hard_zero/hard_two", H5L_TYPE_HARD}, - {"Group2/hard_zero/hard_zero", H5L_TYPE_HARD}, - {"Group2/hard_zero/soft_dangle", H5L_TYPE_SOFT}, - {"Group2/hard_zero/soft_one", H5L_TYPE_SOFT}, - {"Group2/hard_zero/soft_two", H5L_TYPE_SOFT}, - {"Type_one", H5L_TYPE_HARD}, - {"hard_one", H5L_TYPE_HARD} -}; -static const link_visit_t lvisit2[] = { - {"Dataset_two", H5L_TYPE_HARD}, - {"Type_two", H5L_TYPE_HARD}, - {"hard_zero", H5L_TYPE_HARD}, - {"hard_zero/Dataset_zero", H5L_TYPE_HARD}, - {"hard_zero/Group1", H5L_TYPE_HARD}, - {"hard_zero/Group1/Dataset_one", H5L_TYPE_HARD}, - {"hard_zero/Group1/Group2", H5L_TYPE_HARD}, - {"hard_zero/Group1/Type_one", H5L_TYPE_HARD}, - {"hard_zero/Group1/hard_one", H5L_TYPE_HARD}, - {"hard_zero/Type_zero", H5L_TYPE_HARD}, - {"hard_zero/ext_dangle", H5L_TYPE_EXTERNAL}, - {"hard_zero/ext_one", H5L_TYPE_EXTERNAL}, - {"hard_zero/hard_one", H5L_TYPE_HARD}, - {"hard_zero/hard_two", H5L_TYPE_HARD}, - {"hard_zero/hard_zero", H5L_TYPE_HARD}, - {"hard_zero/soft_dangle", H5L_TYPE_SOFT}, - {"hard_zero/soft_one", H5L_TYPE_SOFT}, - {"hard_zero/soft_two", H5L_TYPE_SOFT} -}; - -typedef struct { - unsigned idx; /* Index in link visit structure */ - const link_visit_t *info; /* Pointer to the link visit structure to use */ -} lvisit_ud_t; - - -/* Object visit structs */ +// Object visit structs typedef struct { const char *path; /* Path to object */ H5O_type_t type; /* Type of object */ } obj_visit_t; -static const obj_visit_t ovisit0_old[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_zero", H5O_TYPE_DATASET}, - {"Group1", H5O_TYPE_GROUP}, - {"Group1/Dataset_one", H5O_TYPE_DATASET}, - {"Group1/Group2", H5O_TYPE_GROUP}, - {"Group1/Group2/Dataset_two", H5O_TYPE_DATASET}, - {"Group1/Group2/Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"Group1/Type_one", H5O_TYPE_NAMED_DATATYPE}, - {"Type_zero", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit0_new[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_zero", H5O_TYPE_DATASET}, - {"Group1", H5O_TYPE_GROUP}, - {"Group1/Dataset_one", H5O_TYPE_DATASET}, - {"Group1/Group2", H5O_TYPE_GROUP}, - {"Group1/Group2/Dataset_two", H5O_TYPE_DATASET}, - {"Group1/Group2/Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"Group1/Type_one", H5O_TYPE_NAMED_DATATYPE}, - {"Type_zero", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit1_old[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_one", H5O_TYPE_DATASET}, - {"Group2", H5O_TYPE_GROUP}, - {"Group2/Dataset_two", H5O_TYPE_DATASET}, - {"Group2/Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"Group2/hard_zero", H5O_TYPE_GROUP}, - {"Group2/hard_zero/Dataset_zero", H5O_TYPE_DATASET}, - {"Group2/hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE}, - {"Type_one", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit1_new[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_one", H5O_TYPE_DATASET}, - {"Group2", H5O_TYPE_GROUP}, - {"Group2/Dataset_two", H5O_TYPE_DATASET}, - {"Group2/Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"Group2/hard_zero", H5O_TYPE_GROUP}, - {"Group2/hard_zero/Dataset_zero", H5O_TYPE_DATASET}, - {"Group2/hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE}, - {"Type_one", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit2_old[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_two", H5O_TYPE_DATASET}, - {"Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"hard_zero", H5O_TYPE_GROUP}, - {"hard_zero/Dataset_zero", H5O_TYPE_DATASET}, - {"hard_zero/Group1", H5O_TYPE_GROUP}, - {"hard_zero/Group1/Dataset_one", H5O_TYPE_DATASET}, - {"hard_zero/Group1/Type_one", H5O_TYPE_NAMED_DATATYPE}, - {"hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit2_new[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_two", H5O_TYPE_DATASET}, - {"Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"hard_zero", H5O_TYPE_GROUP}, - {"hard_zero/Dataset_zero", H5O_TYPE_DATASET}, - {"hard_zero/Group1", H5O_TYPE_GROUP}, - {"hard_zero/Group1/Dataset_one", H5O_TYPE_DATASET}, - {"hard_zero/Group1/Type_one", H5O_TYPE_NAMED_DATATYPE}, - {"hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE} -}; +// User data for callback function typedef struct { unsigned idx; /* Index in object visit structure */ const obj_visit_t *info; /* Pointer to the object visit structure to use */ } ovisit_ud_t; -#endif static const char *FILENAME[] = { "link0", "link1.h5", "link2.h5", + "visit", NULL }; @@ -842,6 +581,140 @@ static void test_num_links(hid_t fapl_id, hbool_t new_format) } // test_num_links +// Data for visit on the file +static const obj_visit_t file_visit[] = { + {".", H5O_TYPE_GROUP}, + {"Data", H5O_TYPE_GROUP}, + {"Data/Compressed_Data", H5O_TYPE_DATASET}, + {"Data/Float_Data", H5O_TYPE_DATASET}, +}; + +// Data for visit on the group +static const obj_visit_t group_visit[] = { + {".", H5O_TYPE_GROUP}, + {"Compressed_Data", H5O_TYPE_DATASET}, + {"Float_Data", H5O_TYPE_DATASET}, +}; + +const H5std_string FILE_NAME("tvisit.h5"); +const H5std_string GROUP_NAME("/Data"); +const H5std_string DSET1_NAME("/Data/Compressed_Data"); +const H5std_string DSET2_NAME("/Data/Float_Data"); +const int RANK = 2; +const int DIM1 = 2; + +// Operator function +static int visit_obj_cb(H5Object& obj, const H5std_string name, const H5O_info_t *oinfo, void *_op_data) +{ + ovisit_ud_t *op_data = static_cast <ovisit_ud_t *>(_op_data); + + // Check for correct object information + if(strcmp(op_data->info[op_data->idx].path, name.c_str())) return(H5_ITER_ERROR); + if(op_data->info[op_data->idx].type != oinfo->type) return(H5_ITER_ERROR); + + // Advance to next location + op_data->idx++; + + return(H5_ITER_CONT); +} + +/*------------------------------------------------------------------------- + * Function: test_visit + * + * Purpose Test H5Object::visit + * + * Return None + * + * February 8, 2019 + *------------------------------------------------------------------------- + */ +static void test_visit(hid_t fapl_id, hbool_t new_format) +{ + hsize_t dims[2]; + hsize_t cdims[2]; + char filename[NAME_BUF_SIZE]; + + if(new_format) + SUBTEST("H5Object::visit (w/new group format)") + else + SUBTEST("H5Object::visit") + + try + { + // Use the file access template id to create a file access prop. list + FileAccPropList fapl(fapl_id); + + // Build the hdf5 file name and create the file + h5_fixname(FILENAME[3], fapl_id, filename, sizeof filename); + H5File *file = new H5File(filename, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl); + + // Create a group + Group* group = new Group(file->createGroup(GROUP_NAME)); + + // Create a chunked/compressed dataset within this group specified by path + dims[0] = 20; + dims[1] = 2; + cdims[0] = 2; + cdims[1] = 2; + DataSpace *dataspace = new DataSpace(RANK, dims); // create new dspace + DSetCreatPropList ds_creatplist; // create dataset creation prop list + ds_creatplist.setChunk(2, cdims); // then modify it for compression + ds_creatplist.setDeflate(6); + + DataSet* dataset = new DataSet(file->createDataSet(DSET1_NAME, + PredType::NATIVE_INT, *dataspace, ds_creatplist)); + + delete dataset; + delete dataspace; + + // Create another dataset + dims[0] = 5; + dims[1] = 2; + dataspace = new DataSpace(RANK, dims); // create second dspace + dataset = new DataSet(file->createDataSet(DSET2_NAME, + PredType::NATIVE_FLOAT, *dataspace)); + + // Close everything + delete dataset; + delete dataspace; + delete group; + delete file; + + // Reopen the file and group in the file. + file = new H5File(filename, H5F_ACC_RDWR); + group = new Group(file->openGroup("Data")); + + // Open the group + dataset = new DataSet(group->openDataSet(DSET2_NAME)); + delete dataset; + + // Visit objects in the file + ovisit_ud_t udata; /* User-data for visiting */ + udata.idx = 0; + udata.info = file_visit; + + file->visit(H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC); + + // Visit objects in the group + udata.idx = 0; + udata.info = group_visit; + + group->visit(H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC); + + // Close the group and file. + delete group; + delete file; + + PASSED(); + } // end of try block + catch (Exception& E) + { + cerr << "in catch" << endl; + issue_fail_msg("test_visit()", __LINE__, __FILE__, E.getCDetailMsg()); + } +} // test_visit() + + /*------------------------------------------------------------------------- * Function: test_links * @@ -858,7 +731,8 @@ void test_links() hid_t fapl_id, fapl2_id; /* File access property lists */ unsigned new_format; /* Whether to use the new format or not */ - fapl_id = h5_fileaccess(); + if((fapl_id = h5_fileaccess()) < 0) + throw Exception("test_links", "Unable to get file access property list"); // Output message about test being performed MESSAGE(5, ("Testing Various Links\n")); @@ -891,24 +765,18 @@ void test_links() test_move(my_fapl_id, new_format); test_copy(my_fapl_id, new_format); test_lcpl(my_fapl_id, new_format); + test_visit(my_fapl_id, new_format); } /* end for */ /* Close 2nd FAPL */ H5Pclose(fapl2_id); h5_clean_files(FILENAME, fapl_id); - - /* Test that external links can be used after a library reset. MUST be - * called last so the reset doesn't interfere with the property lists. This - * routine will delete its own file. */ - /* nerrors += external_reset_register() < 0 ? 1 : 0; - */ } catch (Exception& E) { issue_fail_msg("test_links()", __LINE__, __FILE__, E.getCDetailMsg()); } - } @@ -926,7 +794,3 @@ void cleanup_links() HDremove(FILENAME[0]); HDremove(FILENAME[1]); } - - - - diff --git a/c++/test/tobject.cpp b/c++/test/tobject.cpp index 537716f..232ece2 100644 --- a/c++/test/tobject.cpp +++ b/c++/test/tobject.cpp @@ -609,10 +609,121 @@ static void test_getobjectinfo_same_file() catch (Exception& E) { cerr << " in Exception " << E.getCFuncName() << "detail: " << E.getCDetailMsg() << endl; - issue_fail_msg("test_file_name()", __LINE__, __FILE__, E.getCDetailMsg()); + issue_fail_msg("test_getobjectinfo_same_file()", __LINE__, __FILE__, E.getCDetailMsg()); + } + +} // test_getobjectinfo_same_file + +/*------------------------------------------------------------------------- + * Function: test_intermediate_groups + * + * Purpose Test that intermediate groups are created as specified by + * the property setting. + * + * Return None + * + * April, 2019 + *------------------------------------------------------------------------- + */ +const H5std_string FILE_INTERGRPS("tobject_intergrps.h5"); +const H5std_string GROUP10NAME("/group10"); +const H5std_string GROUP11NAME("/group10/group11"); +const H5std_string GROUP12NAME("/group10/group11/group12"); +const H5std_string GROUP13NAME("/group10/group11/group12/group13"); +const H5std_string GROUP14NAME("/group10/group11/group12/group13/group14"); +const H5std_string GROUP14FROM13NAME("group14"); +const H5std_string GROUP20NAME("/group20"); +const H5std_string GROUP21NAME("/group20/group21"); +const H5std_string GROUP22NAME("group21/group22"); +const H5std_string GROUP22FULLNAME("/group20/group21/group22"); +static void test_intermediate_groups() +{ + // Output message about test being performed + SUBTEST("Group::set/getCreateIntermediateGroup"); + + try { + // Create a new HDF5 file + H5File file(FILE_INTERGRPS, H5F_ACC_TRUNC); + + // Create a link create property list and set the "create + // intermediate groups" flag + LinkCreatPropList lcpl; + lcpl.setCreateIntermediateGroup(true); + + // Verify value of create missing groups flag + bool crt_int_grps = lcpl.getCreateIntermediateGroup(); + verify_val(crt_int_grps, true, "LinkCreatPropList::getCreateIntermediateGroup", __LINE__, __FILE__); + + // Create GROUP12NAME with creating missing groups + Group grp12(file.createGroup(GROUP12NAME, lcpl)); + + // Missing groups: GROUP10NAME and GROUP11NAME + + // Create GROUP14NAME without the use of link create plist, should + // fail because group GROUP13NAME is missing + try { + Group grp14_nopl(file.createGroup(GROUP14NAME)); + } catch (FileIException& expected1) {} // Failure is ignored + + // Create GROUP14NAME with the flag to create missing groups set + // to FALSE, should fail because group GROUP13NAME is missing + + // Reset flag to not create missing groups + lcpl.setCreateIntermediateGroup(false); + + // Verify value of create missing groups flag + crt_int_grps = lcpl.getCreateIntermediateGroup(); + verify_val(crt_int_grps, false, "LinkCreatPropList::getCreateIntermediateGroup", __LINE__, __FILE__); + + try { + Group grp14_false(file.createGroup(GROUP14NAME, lcpl)); + } catch (FileIException& expected2) {} // Failure is ignored + + // Set the flag to create missing groups set to TRUE + lcpl.setCreateIntermediateGroup(true); + crt_int_grps = lcpl.getCreateIntermediateGroup(); + verify_val(crt_int_grps, true, "LinkCreatPropList::getCreateIntermediateGroup", __LINE__, __FILE__); + + + // Create GROUP14NAME with the use of link create plist + Group grp14(file.createGroup(GROUP14NAME, lcpl)); + + // Missing groups: GROUP13NAME + + // Create group GROUP20NAME + Group grp20(file.createGroup(GROUP20NAME)); + + // Create group GROUP22NAME with missing group GROUP21NAME + Group grp22(grp20.createGroup(GROUP22NAME, lcpl)); + + // Close groups and file + grp12.close(); + grp14.close(); + grp20.close(); + grp22.close(); + file.close(); + + // Reopen the file + file.openFile(FILE_INTERGRPS, H5F_ACC_RDWR); + + // Open the missing groups and various combinations + Group grp10(file.openGroup(GROUP10NAME)); + Group grp11(file.openGroup(GROUP11NAME)); + Group grp13(file.openGroup(GROUP13NAME)); + Group grp14from13(grp13.openGroup(GROUP14FROM13NAME)); + Group grp21(file.openGroup(GROUP21NAME)); + Group grp22fromfile(file.openGroup(GROUP22FULLNAME)); + + PASSED(); + } // end of try block + // catch all other exceptions + catch (Exception& E) + { + cerr << " in Exception " << E.getCFuncName() << "detail: " << E.getCDetailMsg() << endl; + issue_fail_msg("test_intermediate_groups()", __LINE__, __FILE__, E.getCDetailMsg()); } -} // test_h5o_getinfo_same_file +} // test_intermediate_groups /*------------------------------------------------------------------------- * Function: test_object @@ -631,12 +742,13 @@ void test_object() // Output message about test being performed MESSAGE(5, ("Testing Object Functions\n")); - test_get_objname(); // Test get object name from groups/datasets - test_existance(); // Test check for object existance - test_get_objname_ontypes(); // Test get object name from types - test_get_objtype(); // Test get object type - test_open_object_header(); // Test object header functions (H5O) - test_getobjectinfo_same_file(); // Test object info in same file + test_get_objname(); // Test get object name from groups/datasets + test_existance(); // Test check for object existance + test_get_objname_ontypes(); // Test get object name from types + test_get_objtype(); // Test get object type + test_open_object_header(); // Test object header functions (H5O) + test_getobjectinfo_same_file(); // Test object info in same file + test_intermediate_groups(); // Test intermediate group property } // test_object |