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_type_id.cc.h"
|
||||||
#include "h5_group.cc.h"
|
#include "h5_group.cc.h"
|
||||||
#include "h5_table.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
|
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue