HDF5: Groups and attributes creation can be reused

This commit is contained in:
2026-03-29 13:22:08 +02:00
parent 91dd670043
commit cd0fa49f73
2 changed files with 155 additions and 49 deletions

View File

@@ -315,76 +315,119 @@ void HDF5Fapl::SetVersionTo1p10orNewer() {
H5Pset_libver_bounds(id, H5F_LIBVER_V110, H5F_LIBVER_LATEST);
}
template <typename T>
static HDF5Object& WriteOrCreateScalarAttr(HDF5Object& object, const std::string& name, const T& val) {
HDF5DataSpace dataspace;
HDF5DataType datatype(val);
hid_t attr_id = -1;
if (H5Aexists(object.GetID(), name.c_str()) > 0) {
attr_id = H5Aopen(object.GetID(), name.c_str(), H5P_DEFAULT);
if (attr_id < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Cannot open attribute " + name);
hid_t existing_type = H5Aget_type(attr_id);
if (existing_type < 0) {
H5Aclose(attr_id);
throw JFJochException(JFJochExceptionCategory::HDF5, "Cannot get attribute type " + name);
}
const bool recreate =
(H5Tget_class(existing_type) != H5Tget_class(datatype.GetID())) ||
(H5Tget_size(existing_type) != H5Tget_size(datatype.GetID()));
H5Tclose(existing_type);
H5Aclose(attr_id);
if (recreate) {
if (H5Adelete(object.GetID(), name.c_str()) < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Cannot delete attribute " + name);
attr_id = H5Acreate2(object.GetID(), name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
} else {
attr_id = H5Aopen(object.GetID(), name.c_str(), H5P_DEFAULT);
}
} else {
attr_id = H5Acreate2(object.GetID(), name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
}
if (attr_id < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Cannot create/open attribute " + name);
herr_t ret = H5Awrite(attr_id, datatype.GetID(), &val);
H5Aclose(attr_id);
if (ret < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Attribute write unsuccessful");
return object;
}
HDF5Object & HDF5Object::Attr(const std::string &name, const std::string &val) {
HDF5DataSpace dataspace;
HDF5DataType datatype(val);
hid_t attr_id = H5Acreate2(id, name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
hid_t attr_id = -1;
if (H5Aexists(id, name.c_str()) > 0) {
attr_id = H5Aopen(id, name.c_str(), H5P_DEFAULT);
if (attr_id < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Cannot open attribute " + name);
hid_t existing_type = H5Aget_type(attr_id);
if (existing_type < 0) {
H5Aclose(attr_id);
throw JFJochException(JFJochExceptionCategory::HDF5, "Cannot get attribute type " + name);
}
const bool recreate =
(H5Tget_class(existing_type) != H5T_STRING) ||
(H5Tget_size(existing_type) < val.length() + 1);
H5Tclose(existing_type);
H5Aclose(attr_id);
if (recreate) {
if (H5Adelete(id, name.c_str()) < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Cannot delete attribute " + name);
attr_id = H5Acreate2(id, name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
} else {
attr_id = H5Aopen(id, name.c_str(), H5P_DEFAULT);
}
} else {
attr_id = H5Acreate2(id, name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
}
if (attr_id < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Cannot create/open attribute " + name);
herr_t ret = H5Awrite(attr_id, datatype.GetID(), val.c_str());
H5Aclose(attr_id);
if (ret < 0) throw JFJochException(JFJochExceptionCategory::HDF5, "Attribute write unsuccessful");
if (ret < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Attribute write unsuccessful");
return *this;
}
HDF5Object & HDF5Object::Attr(const std::string &name, int32_t val) {
HDF5DataSpace dataspace;
HDF5DataType datatype(val);
hid_t attr_id = H5Acreate2(id, name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
herr_t ret = H5Awrite(attr_id, datatype.GetID(), &val);
H5Aclose(attr_id);
if (ret < 0) throw JFJochException(JFJochExceptionCategory::HDF5, "Atrribute write unsucessful");
return *this;
return WriteOrCreateScalarAttr(*this, name, val);
}
HDF5Object & HDF5Object::Attr(const std::string &name, uint32_t val) {
HDF5DataSpace dataspace;
HDF5DataType datatype(val);
hid_t attr_id = H5Acreate2(id, name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
herr_t ret = H5Awrite(attr_id, datatype.GetID(), &val);
H5Aclose(attr_id);
if (ret < 0) throw JFJochException(JFJochExceptionCategory::HDF5, "Atrribute write unsucessful");
return *this;
return WriteOrCreateScalarAttr(*this, name, val);
}
HDF5Object & HDF5Object::Attr(const std::string &name, int64_t val) {
HDF5DataSpace dataspace;
HDF5DataType datatype(val);
hid_t attr_id = H5Acreate2(id, name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
herr_t ret = H5Awrite(attr_id, datatype.GetID(), &val);
H5Aclose(attr_id);
if (ret < 0) throw JFJochException(JFJochExceptionCategory::HDF5, "Atrribute write unsucessful");
return *this;
return WriteOrCreateScalarAttr(*this, name, val);
}
HDF5Object & HDF5Object::Attr(const std::string &name, uint64_t val) {
HDF5DataSpace dataspace;
HDF5DataType datatype(val);
hid_t attr_id = H5Acreate2(id, name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
herr_t ret = H5Awrite(attr_id, datatype.GetID(), &val);
H5Aclose(attr_id);
if (ret < 0) throw JFJochException(JFJochExceptionCategory::HDF5, "Atrribute write unsucessful");
return *this;
return WriteOrCreateScalarAttr(*this, name, val);
}
HDF5Object & HDF5Object::Attr(const std::string &name, double val) {
HDF5DataSpace dataspace;
HDF5DataType datatype(val);
hid_t attr_id = H5Acreate2(id, name.c_str(), datatype.GetID(), dataspace.GetID(), H5P_DEFAULT, H5P_DEFAULT);
herr_t ret = H5Awrite(attr_id, datatype.GetID(), &val);
H5Aclose(attr_id);
if (ret < 0) throw JFJochException(JFJochExceptionCategory::HDF5, "Atrribute write unsucessful");
return *this;
return WriteOrCreateScalarAttr(*this, name, val);
}
HDF5Object & HDF5Object::Attr(const std::string &name, const std::vector<double> &val) {
@@ -632,14 +675,19 @@ HDF5Group::HDF5Group(const HDF5Object& parent, const std::string &name) : HDF5Gr
}
HDF5Group::HDF5Group(const HDF5Object& parent, const char *name) : HDF5Object() {
id = H5Gcreate(parent.GetID(), name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (H5Lexists(parent.GetID(), name, H5P_DEFAULT) > 0)
id = H5Gopen(parent.GetID(), name, H5P_DEFAULT);
else
id = H5Gcreate(parent.GetID(), name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (id < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Cannot open/create HDF5 group " + std::string(name));
}
HDF5Group::~HDF5Group() {
H5Gclose(id);
}
HDF5File::HDF5File(const std::string& filename, bool v1_10) : HDF5Object() {
HDF5Fapl fapl;