diff --git a/modules/c++/hdf5.lite/include/hdf5/lite/Info.h b/modules/c++/hdf5.lite/include/hdf5/lite/Info.h index 860f91460..b5705b47f 100644 --- a/modules/c++/hdf5.lite/include/hdf5/lite/Info.h +++ b/modules/c++/hdf5.lite/include/hdf5/lite/Info.h @@ -41,10 +41,6 @@ namespace hdf5 { namespace lite { -struct GroupInfo final -{ -}; - enum class Class { NoClass = -1, /**< error */ @@ -80,9 +76,8 @@ struct DatasetInfo final // Attributes }; -struct FileInfo final +struct GroupInfo { - std::string filename; // could be a URL, so not std::filesystem::path std::string name; std::vector groups; std::vector datasets; @@ -91,6 +86,11 @@ struct FileInfo final // Attributes }; +struct FileInfo final : public GroupInfo +{ + std::string filename; // could be a URL, so not std::filesystem::path +}; + CODA_OSS_API FileInfo fileInfo(coda_oss::filesystem::path); CODA_OSS_API FileInfo fileInfo(coda_oss::filesystem::path, std::string loc); diff --git a/modules/c++/hdf5.lite/source/Info.cpp b/modules/c++/hdf5.lite/source/Info.cpp index 230ee1934..9317869c6 100644 --- a/modules/c++/hdf5.lite/source/Info.cpp +++ b/modules/c++/hdf5.lite/source/Info.cpp @@ -27,6 +27,39 @@ #include "H5.h" #include "hdf5.lite.h" + +// https://docs.hdfgroup.org/archive/support/HDF5/doc1.8/cpplus_RM/h5group_8cpp-example.html +static herr_t group_info(hid_t loc_id, const char *name, const H5L_info_t* /*linfo*/, void *opdata) +{ + // only interested in groups + const auto group = H5Gopen2(loc_id, name, H5P_DEFAULT); + if (group > 0) + { + H5Gclose(group); + + hdf5::lite::GroupInfo groupInfo; + groupInfo.name = name; + + auto pRetval = static_cast*>(opdata); + pRetval->push_back(groupInfo); + } + + return 0; +} +static std::vector getGroups(H5::Group& group) +{ + std::vector retval; + + const auto herr = H5Literate(group.getId(), H5_INDEX_NAME, H5_ITER_INC, nullptr /*idx*/, group_info, &retval); + if (herr != 0) + { + // How can this happen? + throw std::logic_error("H5Literate failed."); + } + + return retval; + } + // https://docs.hdfgroup.org/archive/support/HDF5/doc1.8/cpplus_RM/readdata_8cpp-example.html static hdf5::lite::FileInfo fileInfo_(coda_oss::filesystem::path filename, std::string loc) { @@ -38,7 +71,9 @@ static hdf5::lite::FileInfo fileInfo_(coda_oss::filesystem::path filename, std:: * Open the specified file and the specified dataset in the file. */ H5::H5File file(retval.filename, H5F_ACC_RDONLY); - const auto group = file.openGroup(retval.name); + auto group = file.openGroup(retval.name); + + retval.groups = getGroups(group); return retval; } diff --git a/modules/c++/hdf5.lite/unittests/test_hdf5info.cpp b/modules/c++/hdf5.lite/unittests/test_hdf5info.cpp index 5a77fb416..f5247d6ca 100644 --- a/modules/c++/hdf5.lite/unittests/test_hdf5info.cpp +++ b/modules/c++/hdf5.lite/unittests/test_hdf5info.cpp @@ -43,6 +43,7 @@ TEST_CASE(test_hdf5Info) const auto info = hdf5::lite::fileInfo(path); TEST_ASSERT_EQ(path.string(), info.filename); TEST_ASSERT_EQ("/", info.name); + TEST_ASSERT_EQ(info.groups.size(), 4); } TEST_CASE(test_hdf5Info_IOException) @@ -69,11 +70,12 @@ TEST_CASE(test_hdf5Info_loc) TEST_ASSERT_EQ(path.string(), info.filename); TEST_ASSERT_EQ("/g4", info.name); + TEST_ASSERT_TRUE(info.groups.empty()); } TEST_MAIN( TEST_CHECK(test_hdf5Info); TEST_CHECK(test_hdf5Info_IOException); - //TEST_CHECK(test_hdf5Info_loc); + TEST_CHECK(test_hdf5Info_loc); )