This commit is contained in:
parent
035ae78785
commit
30a3c0b756
11 changed files with 165 additions and 34 deletions
|
@ -33,11 +33,16 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "[";
|
ss << "[";
|
||||||
|
if(a.size() == 0){
|
||||||
|
ss << "]";
|
||||||
|
}
|
||||||
|
else {
|
||||||
auto it = a.begin();
|
auto it = a.begin();
|
||||||
for(; it != a.end()-1; ++it){
|
for(; it != a.end()-1; ++it){
|
||||||
ss << toString(*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 << "(";
|
||||||
|
if constexpr(N == 0){
|
||||||
|
ss << ")";
|
||||||
|
}
|
||||||
|
else {
|
||||||
auto it = a.begin();
|
auto it = a.begin();
|
||||||
for(; it != a.end()-1; ++it){
|
for(; it != a.end()-1; ++it){
|
||||||
ss << toString(*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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 << "'" );
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace CNORXZ
|
||||||
|
|
||||||
Group& Group::open()
|
Group& Group::open()
|
||||||
{
|
{
|
||||||
|
if(not isOpen()){
|
||||||
if(this->exists()){
|
if(this->exists()){
|
||||||
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT );
|
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT );
|
||||||
}
|
}
|
||||||
|
@ -38,6 +39,7 @@ namespace CNORXZ
|
||||||
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
|
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
|
||||||
}
|
}
|
||||||
this->mkCont();
|
this->mkCont();
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue