С++ HDF5 извлекает один член составного типа данных

Я пишу библиотеку С++, которая читает файлы hdf5, созданные другой библиотекой.

Эти файлы hdf5 содержат множество составных наборов данных с различными составными типами данных. Я хочу перевести каждый составной тип данных в структуру C++.

Для строк (переменной длины или массива символов фиксированного размера) я хочу использовать std::string в структуре С++.

В настоящее время я использую промежуточную структуру C (используя переменные char* или char[]), которую затем преобразую в окончательную структуру C++. Однако это приводит к большому количеству шаблонного кода.

Если бы я мог извлечь элементы данных по членам, я мог бы сделать что-то вроде:

std::string name = extract<std::string>(d,"name");

где d — составной набор данных.

Является ли это возможным


person Thomas    schedule 21.01.2017    source источник
comment
Являются ли элементы, которые вы хотите извлечь, всегда строками? Или у них много разных типов данных?   -  person bnaecker    schedule 21.01.2017
comment
Члены имеют смешанные типы.   -  person Thomas    schedule 21.01.2017


Ответы (1)


Я нашел рабочее решение. Выкладываю сюда, может кому пригодится. Идея состоит в том, чтобы создать объект CompoundExtractor, который содержит буфер, в котором считывается все соединение. Затем можно извлечь элементы один за другим, используя метод извлечения шаблона. На данном этапе соответствующая специализация (здесь не сообщается) позволяет правильно обрабатывать строки. С уважением,

struct MADNEX_VISIBILITY_EXPORT CompoundExtractor
{
  /*!
   * \brief constructor
   * \param[in] d: data set
   */
  CompoundExtractor(const DataSet&);
  //! destructor
  ~CompoundExtractor();
  /*!
   * \return a member of the compound of the given type
   * \param[in] n: member name
   */
  template<typename T>
  T extract(const std::string&) const;
  /*!
   * \return a member of the compound of the given type
   * \param[in] n: member name
   */
  template<typename T>
  T extract(const char *) const;
private:
  //! the description of the compound data type
  H5::CompType ctype;
  //! an intermediate storage for the compound data type
  std::vector<char> data;
}; // end of CompoundExtractor

template<typename T>
T CompoundExtractor::extract(const char *n) const{
  const auto i = this->ctype.getMemberIndex(n);
  const auto o = this->ctype.getMemberOffset(i);
  return *(reinterpret_cast<const T *>(this->data.data()+o));
} // end of CompoundExtractor::extract

template<typename T>
T CompoundExtractor::extract(const std::string& n) const{
  const auto i = this->ctype.getMemberIndex(n);
  const auto o = this->ctype.getMemberOffset(i);
  return *(reinterpret_cast<const T *>(this->data.data()+o));
} // end of CompoundExtractor::extract

CompoundExtractor::CompoundExtractor(const DataSet& d)
{
  const auto dtype = d.getDataType();
  if(dtype.getClass()!=H5T_COMPOUND){
    throw(std::runtime_error("CompoundExtractor: invalid data set"));
  }
  this->ctype = H5::CompType(d);
  this->data.resize(ctype.getSize());
  d.read(this->data.data(),ctype);
}

CompoundExtractor::~CompoundExtractor() = default;
person Thomas    schedule 22.01.2017