h5: simple attribute handling (to be tested)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
Christian Zimmermann 2024-01-25 01:19:26 +01:00
parent d5b42c9c00
commit 035ae78785
4 changed files with 184 additions and 3 deletions

View file

@ -1,4 +1,5 @@
#include "h5_content_base.cc.h"
#include "h5_type_id.cc.h" #include "h5_type_id.cc.h"
#include "h5_group.cc.h" #include "h5_group.cc.h"
#include "h5_table.cc.h" #include "h5_table.cc.h"

View file

@ -0,0 +1,98 @@
#ifndef __cxz_h5_content_base_cc_h__
#define __cxz_h5_content_base_cc_h__
#include "h5_content_base.h"
namespace CNORXZ
{
namespace hdf5
{
namespace
{
template <typename T>
struct CreateAttribute
{
static inline herr_t write(hid_t id, const String& name, const T& v)
{
CXZ_ERROR("type " << typeid(v).name() << " not supported (name "
<< name << ", id = " << id << ")");
return 0;
}
};
template <>
struct CreateAttribute<Int>
{
static inline herr_t write(hid_t id, const String& name, const Int& v)
{
const hsize_t dim = 1;
const hid_t type_id = H5Tarray_create(H5T_NATIVE_INT, 1, &dim);
const hid_t space_id = H5Screate(H5S_SCALAR);
const hid_t attr_id = H5Acreate(id, name.c_str(), type_id, space_id, H5P_DEFAULT,
H5P_DEFAULT);
const herr_t err = H5Awrite(attr_id, type_id, &v);
H5Aclose(attr_id);
H5Sclose(space_id);
H5Tclose(type_id);
return err;
}
};
template <>
struct CreateAttribute<Double>
{
static inline herr_t write(hid_t id, const String& name, const Double& v)
{
const hsize_t dim = 1;
const hid_t type_id = H5Tarray_create(H5T_NATIVE_DOUBLE, 1, &dim);
const hid_t space_id = H5Screate(H5S_SCALAR);
const hid_t attr_id = H5Acreate(id, name.c_str(), type_id, space_id, H5P_DEFAULT,
H5P_DEFAULT);
const herr_t err = H5Awrite(attr_id, type_id, &v);
H5Aclose(attr_id);
H5Sclose(space_id);
H5Tclose(type_id);
return err;
}
};
template <>
struct CreateAttribute<String>
{
static inline herr_t write(hid_t id, const String& name, const String& v)
{
const hsize_t len = v.size();
const hid_t type_id = H5Tcreate(H5T_STRING, len);
const hid_t space_id = H5Screate(H5S_SCALAR);
const hid_t attr_id = H5Acreate(id, name.c_str(), type_id, space_id, H5P_DEFAULT,
H5P_DEFAULT);
const herr_t err = H5Awrite(attr_id, type_id, v.c_str());
H5Aclose(attr_id);
H5Sclose(space_id);
H5Tclose(type_id);
return err;
}
};
template <typename T>
inline herr_t writeAttr(hid_t id, const String& name, const T& v, hid_t space_id)
{
return CreateAttribute<T>::write(id, name, v, space_id);
}
}
template <typename T>
ContentBase& ContentBase::addAttribute(const String& name, const T& value)
{
const herr_t err = writeAttr(mId, name, value);
CXZ_ASSERT(err >= 0, "error while writing attribute " << name);
return *this;
}
}
}
#endif

View file

@ -10,6 +10,8 @@ namespace CNORXZ
{ {
namespace hdf5 namespace hdf5
{ {
// TODO: IO save error handling !!!
enum class ContentType { enum class ContentType {
ATTR = 1, ATTR = 1,
FILE = 2, FILE = 2,
@ -42,9 +44,9 @@ namespace CNORXZ
template <typename T> template <typename T>
ContentBase& addAttribute(const String& name, const T& value); ContentBase& addAttribute(const String& name, const T& value);
DType getAttribute(const String& name) const; DType getAttribute(const String& name) const;
bool isAttribute(const String& name) const; bool attributeExists(const String& name) const;
String getAttributesAsString() const; Vector<DType> getAttributes() const;
String getRecursiveAttributesAsString() const; // + all parent's attributes Vector<DType> getRecursiveAttributes() const; // + all parent's attributes
protected: protected:
String mName; String mName;

View file

@ -28,5 +28,85 @@ namespace CNORXZ
{ {
return mId; return mId;
} }
DType ContentBase::getAttribute(const String& name) const
{
CXZ_ASSERT(attributeExists(name), "no attribute with name '" << name
<< "' in object " << mName);
const hid_t attr = H5Aopen(mId, name.c_str(), H5P_DEFAULT);
CXZ_ASSERT(attr != H5I_INVALID_HID, "error while reading attribute " << name);
const hid_t atype_id = H5Aget_type(attr);
CXZ_ASSERT(atype_id != H5I_INVALID_HID,
"error while determining type of attribute " << name);
const H5T_class_t tc = H5Tget_class(atype_id);
DType o;
switch(tc){
case H5T_INTEGER: {
Int v;
H5Aread(attr, atype_id, &v);
o = DType(v);
break;
}
case H5T_FLOAT: {
Double v;
H5Aread(attr, atype_id, &v);
o = DType(v);
break;
}
case H5T_STRING: {
const SizeT asize = H5Tget_size(atype_id);
Vector<char> v(asize);
H5Aread(attr, atype_id, v.data());
o = DType( String( v.data() ) );
break;
}
default:
CXZ_ERROR("attribute type id " << atype_id << " not supported");
}
H5Tclose(atype_id);
H5Aclose(attr);
return o;
}
bool ContentBase::attributeExists(const String& name) const
{
CXZ_ASSERT(isOpen(), "tried to get attribute of closed object");
const htri_t ret = H5Aexists(mId, name.c_str());
CXZ_ASSERT(ret > 0, "error while reading attribute " << name);
return ret;
}
Vector<DType> ContentBase::getAttributes() const
{
CXZ_ASSERT(isOpen(), "tried to get attribute of closed object");
struct ItData
{
Vector<DType> d;
const ContentBase* _this;
} itdata;
itdata._this = this;
auto itop = [](hid_t loc_id, const char *attr_name,
const H5A_info_t* ainfo, void *op_data)
{
ItData* x = reinterpret_cast<ItData*>(op_data);
x->d.push_back( x->_this->getAttribute( String(attr_name) ) );
return static_cast<herr_t>(0);
};
H5Aiterate(id(), H5_INDEX_NAME, H5_ITER_NATIVE, nullptr,
itop, &itdata);
return itdata.d;
}
Vector<DType> ContentBase::getRecursiveAttributes() const
{
Vector<DType> out = getAttributes();
if(mParent){
Vector<DType> par = mParent->getRecursiveAttributes();
out.insert(out.begin(), par.begin(), par.end());
}
return out;
}
} }
} }