dev #2
11 changed files with 165 additions and 34 deletions
|
@ -33,11 +33,16 @@ namespace CNORXZ
|
|||
{
|
||||
std::stringstream ss;
|
||||
ss << "[";
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
if(a.size() == 0){
|
||||
ss << "]";
|
||||
}
|
||||
else {
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
}
|
||||
ss << toString(*it) << "]";
|
||||
}
|
||||
ss << toString(*it) << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
@ -46,11 +51,16 @@ namespace CNORXZ
|
|||
{
|
||||
std::stringstream ss;
|
||||
ss << "(";
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
if constexpr(N == 0){
|
||||
ss << ")";
|
||||
}
|
||||
else {
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
}
|
||||
ss << toString(*it) << ")";
|
||||
}
|
||||
ss << toString(*it) << ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
@ -73,6 +83,26 @@ namespace CNORXZ
|
|||
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>
|
||||
String toString(const T& a)
|
||||
{
|
||||
|
|
|
@ -97,6 +97,20 @@ namespace CNORXZ
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -78,9 +78,9 @@ namespace CNORXZ
|
|||
|
||||
|
||||
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);
|
||||
DType getAttribute(const String& name) const;
|
||||
bool attributeExists(const String& name) const;
|
||||
Vector<DType> getAttributes() const;
|
||||
Vector<DType> getRecursiveAttributes() const; // + all parent's attributes
|
||||
std::map<String,DType> getAttributes() const;
|
||||
std::map<String,DType> getRecursiveAttributes() const; // + all parent's attributes
|
||||
|
||||
protected:
|
||||
String mName;
|
||||
|
|
|
@ -71,6 +71,23 @@ namespace CNORXZ
|
|||
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>
|
||||
decltype(auto) iterRecursive(F&& f) const;
|
||||
|
||||
template <class F>
|
||||
decltype(auto) iter(F&& f);
|
||||
|
||||
template <class F>
|
||||
decltype(auto) iterRecursive(F&& f);
|
||||
|
||||
protected:
|
||||
|
||||
template <typename C, class F>
|
||||
|
|
|
@ -51,9 +51,12 @@ namespace CNORXZ
|
|||
STable& appendRecord(const Tuple<Ts...>& t);
|
||||
STable& appendRecord(const MArray<Tuple<Ts...>>& t);
|
||||
|
||||
MArray<Tuple<Ts...>> read();
|
||||
|
||||
template <class F>
|
||||
decltype(auto) iterRecords(F&& f) const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,11 +56,37 @@ namespace CNORXZ
|
|||
}
|
||||
case H5T_STRING: {
|
||||
const SizeT asize = H5Tget_size(atype_id);
|
||||
Vector<char> v(asize);
|
||||
Vector<char> v(asize+1);
|
||||
H5Aread(attr, atype_id, v.data());
|
||||
o = DType( String( v.data() ) );
|
||||
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:
|
||||
CXZ_ERROR("attribute type id " << atype_id << " not supported");
|
||||
}
|
||||
|
@ -78,12 +104,12 @@ namespace CNORXZ
|
|||
return ret;
|
||||
}
|
||||
|
||||
Vector<DType> ContentBase::getAttributes() const
|
||||
std::map<String,DType> ContentBase::getAttributes() const
|
||||
{
|
||||
CXZ_ASSERT(isOpen(), "tried to get attribute of closed object");
|
||||
struct ItData
|
||||
{
|
||||
Vector<DType> d;
|
||||
std::map<String,DType> d;
|
||||
const ContentBase* _this;
|
||||
} itdata;
|
||||
itdata._this = this;
|
||||
|
@ -91,7 +117,8 @@ namespace CNORXZ
|
|||
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) ) );
|
||||
const String n = attr_name;
|
||||
x->d[n] = x->_this->getAttribute( String(attr_name) );
|
||||
return static_cast<herr_t>(0);
|
||||
};
|
||||
H5Aiterate(id(), H5_INDEX_NAME, H5_ITER_NATIVE, nullptr,
|
||||
|
@ -99,12 +126,12 @@ namespace CNORXZ
|
|||
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){
|
||||
Vector<DType> par = mParent->getRecursiveAttributes();
|
||||
out.insert(out.begin(), par.begin(), par.end());
|
||||
std::map<String,DType> par = mParent->getRecursiveAttributes();
|
||||
out.insert(par.begin(), par.end());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ namespace CNORXZ
|
|||
|
||||
File& File::open()
|
||||
{
|
||||
if(isOpen()){
|
||||
return *this;
|
||||
}
|
||||
Int ex = this->exists();
|
||||
const String fn = this->filename();
|
||||
CXZ_ASSERT( ex != 2, "tried to open non-h5 file '" << fn << "'" );
|
||||
|
|
|
@ -30,14 +30,16 @@ namespace CNORXZ
|
|||
|
||||
Group& Group::open()
|
||||
{
|
||||
if(this->exists()){
|
||||
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT );
|
||||
if(not isOpen()){
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,16 +80,27 @@ namespace
|
|||
File h5f(mFileName, false);
|
||||
EXPECT_FALSE(h5f.ro());
|
||||
h5f.open();
|
||||
h5f.addAttribute("fprop", static_cast<Double>(3.141));
|
||||
h5f.addGroup("gr1");
|
||||
h5f.getGroup("gr1")->addAttribute("att1", String("text"));
|
||||
h5f.addGroup("gr2");
|
||||
h5f.addGroup("foo");
|
||||
h5f.addGroup("moregroups");
|
||||
h5f.addGroup("bar");
|
||||
h5f.getGroup("moregroups")->open().addGroup("evenmore");
|
||||
h5f.getGroup("moregroups")->getGroup("evenmore")->open().addGroup("we");
|
||||
h5f.getGroup("moregroups")->getGroup("evenmore")->addGroup("need");
|
||||
h5f.getGroup("moregroups")->getGroup("evenmore")->addGroup("more");
|
||||
h5f.getGroup("moregroups")->getGroup("evenmore")->addGroup("groups");
|
||||
h5f.addGroup("moregroups");
|
||||
auto moregroups = h5f.getGroup("moregroups");
|
||||
moregroups->open().addGroup("evenmore");
|
||||
auto evenmore = moregroups->getGroup("evenmore");
|
||||
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);
|
||||
h5f.close();
|
||||
}
|
||||
|
@ -100,6 +111,7 @@ namespace
|
|||
h5f.open();
|
||||
h5f.getGroup("gr1")->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();
|
||||
}
|
||||
|
||||
|
@ -114,13 +126,30 @@ namespace
|
|||
auto gr1 = h5f.getGroup("gr1");
|
||||
gr1->open();
|
||||
auto tab = gr1->getTable("tab1");
|
||||
DType att = gr1->getAttribute("att1");
|
||||
EXPECT_EQ(att.str(), "text");
|
||||
VCHECK(tab->path());
|
||||
EXPECT_EQ(tab->fields()->size(), 3u);
|
||||
EXPECT_EQ(tab->records()->size(), 5u);
|
||||
h5f.iter( [](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();
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue