h5: simple attribute handling (to be tested)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
This commit is contained in:
parent
d5b42c9c00
commit
035ae78785
4 changed files with 184 additions and 3 deletions
|
@ -1,4 +1,5 @@
|
|||
|
||||
#include "h5_content_base.cc.h"
|
||||
#include "h5_type_id.cc.h"
|
||||
#include "h5_group.cc.h"
|
||||
#include "h5_table.cc.h"
|
||||
|
|
98
src/opt/hdf5/include/h5_content_base.cc.h
Normal file
98
src/opt/hdf5/include/h5_content_base.cc.h
Normal 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
|
|
@ -10,6 +10,8 @@ namespace CNORXZ
|
|||
{
|
||||
namespace hdf5
|
||||
{
|
||||
// TODO: IO save error handling !!!
|
||||
|
||||
enum class ContentType {
|
||||
ATTR = 1,
|
||||
FILE = 2,
|
||||
|
@ -42,9 +44,9 @@ namespace CNORXZ
|
|||
template <typename T>
|
||||
ContentBase& addAttribute(const String& name, const T& value);
|
||||
DType getAttribute(const String& name) const;
|
||||
bool isAttribute(const String& name) const;
|
||||
String getAttributesAsString() const;
|
||||
String getRecursiveAttributesAsString() const; // + all parent's attributes
|
||||
bool attributeExists(const String& name) const;
|
||||
Vector<DType> getAttributes() const;
|
||||
Vector<DType> getRecursiveAttributes() const; // + all parent's attributes
|
||||
|
||||
protected:
|
||||
String mName;
|
||||
|
|
|
@ -28,5 +28,85 @@ namespace CNORXZ
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue