Commit 550ab08c authored by gbalduzz's avatar gbalduzz
Browse files

Write strings with the native H5 type readable from hdfview.

parent e4650522
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ private:

  bool exists(const std::string& name) const;

  void write(const std::string& name, const std::vector<hsize_t>& size, H5::PredType type,
  void write(const std::string& name, const std::vector<hsize_t>& size, H5::DataType type,
             const void* data);

  std::unique_ptr<H5::H5File> file_;
+6 −6
Original line number Diff line number Diff line
@@ -194,8 +194,8 @@ void OutputParameters::readWrite(ReaderOrWriter& reader_or_writer) {
  }
}

}  // params
}  // phys
}  // dca
}  // namespace params
}  // namespace phys
}  // namespace dca

#endif  // DCA_PHYS_PARAMETERS_OUTPUT_PARAMETERS_HPP
+11 −5
Original line number Diff line number Diff line
@@ -59,16 +59,22 @@ std::string HDF5Reader::get_path() {

bool HDF5Reader::execute(const std::string& name, std::string& value) {
  std::string full_name = get_path() + "/" + name;

  if (!exists(full_name)) {
    return false;
  }

  auto dims = readSize(full_name);
  assert(dims.size() == 1);
  value.resize(dims.at(0));
  H5::DataSet dataset = file_->openDataSet(full_name.c_str());
  const auto type = dataset.getDataType();

  const auto size = type.getSize();
  value.resize(size);

  dataset.read(value.data(), type);

  // Null string case.
  if (value == std::string{0})
    value = "";

  read(full_name, HDF5_TYPE<char>::get_PredType(), value.data());
  return true;
}

+9 −2
Original line number Diff line number Diff line
@@ -83,9 +83,16 @@ std::string HDF5Writer::get_path() {
void HDF5Writer::execute(const std::string& name,
                         const std::string& value)  //, H5File& file, std::string path)
{
  // HDF5 does not allow a datatype of size 0.
  if (value.size() == 0)
    return execute(name, std::string{0});

  std::string full_name = get_path() + '/' + name;

  write(full_name, std::vector<hsize_t>{value.size()}, HDF5_TYPE<char>::get_PredType(), value.data());
  // String type.
  H5::StrType datatype(H5::PredType::C_S1, value.size());

  write(full_name, std::vector<hsize_t>{1}, datatype, value.data());
}

void HDF5Writer::execute(const std::string& name,
@@ -106,7 +113,7 @@ void HDF5Writer::execute(const std::string& name,
  }
}

void HDF5Writer::write(const std::string& name, const std::vector<hsize_t>& dims, H5::PredType type,
void HDF5Writer::write(const std::string& name, const std::vector<hsize_t>& dims, H5::DataType type,
                       const void* data) {
  if (exists(name)) {
    H5::DataSet dataset = file_->openDataSet(name.c_str());
+11 −6
Original line number Diff line number Diff line
@@ -143,22 +143,27 @@ TEST(HDF5ReaderWriterTest, VectorOfArraysReadWrite) {
  reader.close_file();
}

TEST(HDF5ReaderWriterTest, VectorOfStringsReadWrite) {
  std::vector<std::string> s1{"foo", "bar", "baz"};
TEST(HDF5ReaderWriterTest, StringAndVectorOfStringsReadWrite) {
  std::vector<std::string> s_vec1{"foo", "", "baz"};
  std::string s1{"bazinga"};
  const std::string filename = "test_vec_of_strings.hdf5";

  // Create test file.
  dca::io::HDF5Writer writer;
  writer.open_file(filename);
  writer.execute("strings", s1);
  writer.execute("single-string", s1);
  writer.execute("strings", s_vec1);
  writer.close_file();

  // Read test file.
  dca::io::HDF5Reader reader;
  reader.open_file(filename);

  std::vector<std::string> s2;
  EXPECT_TRUE(reader.execute("strings", s2));
  //
  std::vector<std::string> s_vec2;
  std::string s2;
  EXPECT_TRUE(reader.execute("strings", s_vec2));
  EXPECT_TRUE(reader.execute("single-string", s2));
  EXPECT_EQ(s_vec1, s_vec2);
  EXPECT_EQ(s1, s2);
}