dev #2

Merged
chizeta merged 32 commits from dev into main 2024-02-02 20:36:53 +01:00
11 changed files with 165 additions and 34 deletions
Showing only changes of commit 30a3c0b756 - Show all commits

View file

@ -33,11 +33,16 @@ namespace CNORXZ
{ {
std::stringstream ss; std::stringstream ss;
ss << "["; ss << "[";
auto it = a.begin(); if(a.size() == 0){
for(; it != a.end()-1; ++it){ ss << "]";
ss << toString(*it) << ","; }
else {
auto it = a.begin();
for(; it != a.end()-1; ++it){
ss << toString(*it) << ",";
}
ss << toString(*it) << "]";
} }
ss << toString(*it) << "]";
return ss.str(); return ss.str();
} }
@ -46,11 +51,16 @@ namespace CNORXZ
{ {
std::stringstream ss; std::stringstream ss;
ss << "("; ss << "(";
auto it = a.begin(); if constexpr(N == 0){
for(; it != a.end()-1; ++it){ ss << ")";
ss << toString(*it) << ","; }
else {
auto it = a.begin();
for(; it != a.end()-1; ++it){
ss << toString(*it) << ",";
}
ss << toString(*it) << ")";
} }
ss << toString(*it) << ")";
return ss.str(); return ss.str();
} }
@ -73,6 +83,26 @@ namespace CNORXZ
return String("(") + toString(p.first) + "," + toString(p.second) + ")"; return String("(") + toString(p.first) + "," + toString(p.second) + ")";
} }
template <typename T, typename S>
String ToString<std::map<T,S>>::func(const std::map<T,S>& p)
{
std::stringstream ss;
ss << "{";
if(p.size() == 0){
ss << "}";
}
else {
auto it = p.begin();
auto e = p.end();
e--;
for(; it != e; ++it){
ss << toString(it->first) << ":" << toString(it->second) << ",";
}
ss << toString(it->first) << ":" << toString(it->second) << "}";
}
return ss.str();
}
template <typename T> template <typename T>
String toString(const T& a) String toString(const T& a)
{ {

View file

@ -97,6 +97,20 @@ namespace CNORXZ
static String func(const std::pair<T,S>& t); static String func(const std::pair<T,S>& t);
}; };
/** ***
Specialization of ToString for maps
@tparam T key type
@tparam S value type
*/
template <typename T, typename S>
struct ToString<std::map<T,S>>
{
/** cast to string
@param a map to be casted
*/
static String func(const std::map<T,S>& t);
};
/** *** /** ***
Specialization of ToString for DType Specialization of ToString for DType
*/ */

View file

@ -78,9 +78,9 @@ namespace CNORXZ
template <typename T> template <typename T>
inline herr_t writeAttr(hid_t id, const String& name, const T& v, hid_t space_id) inline herr_t writeAttr(hid_t id, const String& name, const T& v)
{ {
return CreateAttribute<T>::write(id, name, v, space_id); return CreateAttribute<T>::write(id, name, v);
} }
} }

View file

@ -45,8 +45,8 @@ namespace CNORXZ
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 attributeExists(const String& name) const; bool attributeExists(const String& name) const;
Vector<DType> getAttributes() const; std::map<String,DType> getAttributes() const;
Vector<DType> getRecursiveAttributes() const; // + all parent's attributes std::map<String,DType> getRecursiveAttributes() const; // + all parent's attributes
protected: protected:
String mName; String mName;

View file

@ -71,6 +71,23 @@ namespace CNORXZ
recursion(c, std::forward<F>(f)); recursion(c, std::forward<F>(f));
}); });
} }
template <class F>
decltype(auto) Group::iter(F&& f)
{
RangePtr gr = *mCont.range()->sub().begin();
auto gi = std::make_shared<UIndex<String>>(gr);
return gi->ifor( operation(std::forward<F>(f), mCont(gi)), NoF{} );
}
template <class F>
decltype(auto) Group::iterRecursive(F&& f)
{
return iter( [&](const auto& c) {
f(c);
recursion(c, std::forward<F>(f));
});
}
} }
} }

View file

@ -48,6 +48,12 @@ namespace CNORXZ
template <class F> template <class F>
decltype(auto) iterRecursive(F&& f) const; decltype(auto) iterRecursive(F&& f) const;
template <class F>
decltype(auto) iter(F&& f);
template <class F>
decltype(auto) iterRecursive(F&& f);
protected: protected:
template <typename C, class F> template <typename C, class F>

View file

@ -51,9 +51,12 @@ namespace CNORXZ
STable& appendRecord(const Tuple<Ts...>& t); STable& appendRecord(const Tuple<Ts...>& t);
STable& appendRecord(const MArray<Tuple<Ts...>>& t); STable& appendRecord(const MArray<Tuple<Ts...>>& t);
MArray<Tuple<Ts...>> read();
template <class F> template <class F>
decltype(auto) iterRecords(F&& f) const; decltype(auto) iterRecords(F&& f) const;
}; };
} }
} }

View file

@ -56,11 +56,37 @@ namespace CNORXZ
} }
case H5T_STRING: { case H5T_STRING: {
const SizeT asize = H5Tget_size(atype_id); const SizeT asize = H5Tget_size(atype_id);
Vector<char> v(asize); Vector<char> v(asize+1);
H5Aread(attr, atype_id, v.data()); H5Aread(attr, atype_id, v.data());
o = DType( String( v.data() ) ); o = DType( String( v.data() ) );
break; break;
} }
case H5T_ARRAY: {
const int ndims = H5Tget_array_ndims(atype_id);
CXZ_ASSERT(ndims, "array of dimension " << ndims << " not supported");
hsize_t dims;
H5Tget_array_dims(atype_id, &dims);
const hid_t att_id = H5Tget_super(atype_id);
const H5T_class_t atc = H5Tget_class(att_id);
switch(atc){
case H5T_INTEGER: {
Vector<Int> v(dims);
H5Aread(attr, atype_id, v.data());
o = DType(v);
break;
}
case H5T_FLOAT: {
Vector<Double> v(dims);
H5Aread(attr, atype_id, v.data());
o = DType(v);
break;
}
default:
CXZ_ERROR("attribute type id " << atype_id << " not supported");
}
H5Tclose(att_id);
break;
}
default: default:
CXZ_ERROR("attribute type id " << atype_id << " not supported"); CXZ_ERROR("attribute type id " << atype_id << " not supported");
} }
@ -78,12 +104,12 @@ namespace CNORXZ
return ret; return ret;
} }
Vector<DType> ContentBase::getAttributes() const std::map<String,DType> ContentBase::getAttributes() const
{ {
CXZ_ASSERT(isOpen(), "tried to get attribute of closed object"); CXZ_ASSERT(isOpen(), "tried to get attribute of closed object");
struct ItData struct ItData
{ {
Vector<DType> d; std::map<String,DType> d;
const ContentBase* _this; const ContentBase* _this;
} itdata; } itdata;
itdata._this = this; itdata._this = this;
@ -91,7 +117,8 @@ namespace CNORXZ
const H5A_info_t* ainfo, void *op_data) const H5A_info_t* ainfo, void *op_data)
{ {
ItData* x = reinterpret_cast<ItData*>(op_data); ItData* x = reinterpret_cast<ItData*>(op_data);
x->d.push_back( x->_this->getAttribute( String(attr_name) ) ); const String n = attr_name;
x->d[n] = x->_this->getAttribute( String(attr_name) );
return static_cast<herr_t>(0); return static_cast<herr_t>(0);
}; };
H5Aiterate(id(), H5_INDEX_NAME, H5_ITER_NATIVE, nullptr, H5Aiterate(id(), H5_INDEX_NAME, H5_ITER_NATIVE, nullptr,
@ -99,12 +126,12 @@ namespace CNORXZ
return itdata.d; return itdata.d;
} }
Vector<DType> ContentBase::getRecursiveAttributes() const std::map<String,DType> ContentBase::getRecursiveAttributes() const
{ {
Vector<DType> out = getAttributes(); std::map<String,DType> out = getAttributes();
if(mParent){ if(mParent){
Vector<DType> par = mParent->getRecursiveAttributes(); std::map<String,DType> par = mParent->getRecursiveAttributes();
out.insert(out.begin(), par.begin(), par.end()); out.insert(par.begin(), par.end());
} }
return out; return out;
} }

View file

@ -28,6 +28,9 @@ namespace CNORXZ
File& File::open() File& File::open()
{ {
if(isOpen()){
return *this;
}
Int ex = this->exists(); Int ex = this->exists();
const String fn = this->filename(); const String fn = this->filename();
CXZ_ASSERT( ex != 2, "tried to open non-h5 file '" << fn << "'" ); CXZ_ASSERT( ex != 2, "tried to open non-h5 file '" << fn << "'" );

View file

@ -30,14 +30,16 @@ namespace CNORXZ
Group& Group::open() Group& Group::open()
{ {
if(this->exists()){ if(not isOpen()){
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT ); if(this->exists()){
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT );
}
else {
mId = H5Gcreate( mParent->id(), mName.c_str(),
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
}
this->mkCont();
} }
else {
mId = H5Gcreate( mParent->id(), mName.c_str(),
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
}
this->mkCont();
return *this; return *this;
} }

View file

@ -80,16 +80,27 @@ namespace
File h5f(mFileName, false); File h5f(mFileName, false);
EXPECT_FALSE(h5f.ro()); EXPECT_FALSE(h5f.ro());
h5f.open(); h5f.open();
h5f.addAttribute("fprop", static_cast<Double>(3.141));
h5f.addGroup("gr1"); h5f.addGroup("gr1");
h5f.getGroup("gr1")->addAttribute("att1", String("text"));
h5f.addGroup("gr2"); h5f.addGroup("gr2");
h5f.addGroup("foo"); h5f.addGroup("foo");
h5f.addGroup("moregroups");
h5f.addGroup("bar"); h5f.addGroup("bar");
h5f.getGroup("moregroups")->open().addGroup("evenmore"); h5f.addGroup("moregroups");
h5f.getGroup("moregroups")->getGroup("evenmore")->open().addGroup("we"); auto moregroups = h5f.getGroup("moregroups");
h5f.getGroup("moregroups")->getGroup("evenmore")->addGroup("need"); moregroups->open().addGroup("evenmore");
h5f.getGroup("moregroups")->getGroup("evenmore")->addGroup("more"); auto evenmore = moregroups->getGroup("evenmore");
h5f.getGroup("moregroups")->getGroup("evenmore")->addGroup("groups"); evenmore->open();
evenmore->addAttribute("moreatt", static_cast<Int>(12));
evenmore->addGroup("we");
evenmore->getGroup("we")->addAttribute("wex", static_cast<Int>(9));
evenmore->getGroup("we")->addAttribute("xy", String("xys"));
evenmore->addGroup("need");
evenmore->getGroup("need")->addAttribute("wex", static_cast<Int>(7));
evenmore->addGroup("more");
evenmore->getGroup("more")->addAttribute("wex", static_cast<Int>(4));
evenmore->addGroup("groups");
evenmore->getGroup("groups")->addAttribute("wex", static_cast<Int>(2));
EXPECT_EQ(h5f.get().size(), 5u); EXPECT_EQ(h5f.get().size(), 5u);
h5f.close(); h5f.close();
} }
@ -100,6 +111,7 @@ namespace
h5f.open(); h5f.open();
h5f.getGroup("gr1")->open().addTable("tab1", mTabA, mFs); h5f.getGroup("gr1")->open().addTable("tab1", mTabA, mFs);
h5f.getGroup("gr2")->open().addTable("tab1", mTabA, mFs); h5f.getGroup("gr2")->open().addTable("tab1", mTabA, mFs);
h5f.getGroup("moregroups")->open().getGroup("evenmore")->open().getGroup("need")->open().addTable("tab1", mTabA, mFs);
h5f.close(); h5f.close();
} }
@ -114,13 +126,30 @@ namespace
auto gr1 = h5f.getGroup("gr1"); auto gr1 = h5f.getGroup("gr1");
gr1->open(); gr1->open();
auto tab = gr1->getTable("tab1"); auto tab = gr1->getTable("tab1");
DType att = gr1->getAttribute("att1");
EXPECT_EQ(att.str(), "text");
VCHECK(tab->path()); VCHECK(tab->path());
EXPECT_EQ(tab->fields()->size(), 3u); EXPECT_EQ(tab->fields()->size(), 3u);
EXPECT_EQ(tab->records()->size(), 5u); EXPECT_EQ(tab->records()->size(), 5u);
h5f.iter( [](const auto& c) { VCHECK(c->path()); } )(); h5f.iter( [](const auto& c) { VCHECK(c->path()); } )();
h5f.iterRecursive( [](const auto& c) { VCHECK(c->path()); } )(); h5f.iterRecursive( [](const auto& c) { VCHECK(c->path()); } )();
h5f.iterRecursive( [](const auto& c) { c->open(); VCHECK(toString(c->getRecursiveAttributes())); } )();
h5f.iterRecursive( [](const auto& c) {
if(c->type() == ContentType::TABLE) { c->open(); VCHECK(toString(c->getRecursiveAttributes())); }
} )();
h5f.close(); h5f.close();
} }
TEST_F(Group_Test, ReadTable)
{
File h5f(mFileName, true);
h5f.open();
auto tab = h5f.getGroup("gr1")->open().getTable("tab1");
EXPECT_EQ(tab->fields()->size(), 3u);
EXPECT_EQ(tab->records()->size(), 5u);
}
} }
// check write to new file // check write to new file