first reCommit
This commit is contained in:
22
nodes/znode.cpp
Normal file
22
nodes/znode.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/***************************************************************************
|
||||
|
||||
source::worx xtree
|
||||
Copyright © 2024-2025 c.holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <znode.h>
|
||||
|
||||
namespace znode
|
||||
{
|
||||
|
||||
int zid::s_Count{0};
|
||||
|
||||
} // namespace znode
|
401
nodes/znode.h
Normal file
401
nodes/znode.h
Normal file
@@ -0,0 +1,401 @@
|
||||
/***************************************************************************
|
||||
|
||||
source::worx xtree
|
||||
Copyright © 2024-2025 c.holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef ZNODE_H
|
||||
#define ZNODE_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
//#include <typeinfo>
|
||||
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
#include <xqmaptor.h>
|
||||
#include <xsingleton.h>
|
||||
|
||||
#include <znode_iterator.h>
|
||||
//#include <znode_vector.h>
|
||||
#include <znode_id.h>
|
||||
#include <znode_payload.h>
|
||||
|
||||
namespace znode
|
||||
{
|
||||
|
||||
/// ----------------- snip 8< -----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// forward declaration of base class zbasic_node ...
|
||||
//template<class str_t>
|
||||
//class zbasic_node;
|
||||
|
||||
// ... used here for conveniance typedef
|
||||
//template<class str_t>
|
||||
//using zshared_node = std::shared_ptr<zbasic_node<str_t>>;
|
||||
|
||||
|
||||
// main class
|
||||
template<class str_t>
|
||||
class zbasic_node : public zid, public zpayload<str_t>, public std::enable_shared_from_this<zbasic_node<str_t>>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
using str_cref = const str_t&;
|
||||
using str_list = std::vector<str_t>;
|
||||
|
||||
//using zshared_node = std::shared_ptr<zbasic_node>;
|
||||
//using znode_list = znode_vector<zbasic_node>;
|
||||
//using znode_list = znode_vector<zshared_node<str_t>>;
|
||||
//using znode_list = std::vector<zshared_node<str_t>>;
|
||||
|
||||
using zweak_node = std::weak_ptr<zbasic_node>;
|
||||
using zshared_node = std::shared_ptr<zbasic_node>;
|
||||
using znode_list = std::vector<zshared_node>;
|
||||
using zshared_cref = const std::shared_ptr<zbasic_node>&;
|
||||
|
||||
//using ziterator = znode_iterator<zshared_node>;
|
||||
using ziterator = znode_iterator<zbasic_node>;
|
||||
|
||||
protected:
|
||||
|
||||
//zbasic_node* _parent;
|
||||
zweak_node _parent;
|
||||
znode_list _children;
|
||||
|
||||
struct match_id
|
||||
{
|
||||
match_id( int match )
|
||||
: _match{match}
|
||||
{}
|
||||
|
||||
bool operator()( zshared_node node )
|
||||
{
|
||||
return _match == node->_id;
|
||||
}
|
||||
|
||||
int _match{};
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static zshared_node make_node( str_cref arg1, str_cref arg2 = "" , zshared_cref parent = nullptr )
|
||||
{
|
||||
return std::make_shared<zbasic_node>( arg1, arg2, parent );
|
||||
}
|
||||
|
||||
zbasic_node() = default;
|
||||
|
||||
// ...
|
||||
zbasic_node( str_cref tag_name, zshared_cref parent = nullptr )
|
||||
//zbasic_node( str_cref tag_name, zbasic_node* parent = nullptr )
|
||||
: zpayload<str_t>{tag_name}, _parent{parent}
|
||||
{
|
||||
//_parent = parent;
|
||||
}
|
||||
|
||||
|
||||
// ...
|
||||
zbasic_node( str_cref tag_name, str_cref value, zshared_cref parent = nullptr )
|
||||
//zbasic_node( str_cref tag_name, str_cref value, zbasic_node* parent = nullptr )
|
||||
: zpayload<str_t>{tag_name,value}
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
|
||||
zbasic_node( str_cref tag_name, const str_list& attributes, zshared_cref parent = nullptr )
|
||||
: zbasic_node{tag_name, parent}
|
||||
{
|
||||
for( str_cref entry : attributes )
|
||||
{
|
||||
str_t key_value, data_value;
|
||||
if( xstr_split_by( entry, "=", key_value, data_value) )
|
||||
set_attribute( key_value, data_value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual ~zbasic_node()
|
||||
{
|
||||
_children.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
virtual zbasic_node* clone() const
|
||||
{
|
||||
|
||||
// start a new node hierarchy with the existing parent
|
||||
zbasic_node* new_me = new zbasic_node( _tag_name, _value, _parent );
|
||||
new_me->_attributes = _attributes;
|
||||
//new_me->_id = _id;
|
||||
// clone my children with myself as new parent.
|
||||
for( zbasic_node* child : _children )
|
||||
new_me->children().push_back( child->clone( new_me ) );
|
||||
return new_me;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
virtual zbasic_node* clone(zbasic_node* new_parent) const
|
||||
{
|
||||
zbasic_node* new_me = new zbasic_node(_tag_name, _value, new_parent );
|
||||
new_me->_attributes = _attributes;
|
||||
for (zbasic_node* child : _children)
|
||||
new_me->children().push_back(child->clone( new_me ));
|
||||
return new_me;
|
||||
}
|
||||
*/
|
||||
|
||||
// STL-ish traverse iterators
|
||||
auto begin()
|
||||
{
|
||||
return ziterator(this);
|
||||
}
|
||||
|
||||
auto end()
|
||||
{
|
||||
return ziterator(nullptr);
|
||||
}
|
||||
|
||||
// ... set_int
|
||||
// ... as_int
|
||||
|
||||
//zweak_node parent()
|
||||
zshared_node parent()
|
||||
{
|
||||
return _parent.lock();
|
||||
}
|
||||
|
||||
//void set_parent( zbasic_node* parent )
|
||||
void set_parent( zshared_node parent )
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
zshared_node sibling()
|
||||
{
|
||||
if( !parent() )
|
||||
//return zshared_node( make_node("WTF1") );
|
||||
return zshared_node();
|
||||
|
||||
znode_list& childs = parent()->_children;
|
||||
auto it = std::find( childs.begin(), childs.end(), this->shared_from_this() );
|
||||
if( ++it != childs.end())
|
||||
return *(it);
|
||||
|
||||
//return zshared_node( make_node("WTF?") );
|
||||
return zshared_node();
|
||||
}
|
||||
|
||||
inline const znode_list& children() const
|
||||
{
|
||||
return _children;
|
||||
}
|
||||
|
||||
bool has_children() const
|
||||
{
|
||||
return !children().empty();
|
||||
}
|
||||
|
||||
zshared_node first_child()
|
||||
{
|
||||
if(!children().empty())
|
||||
return children().front();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
zshared_node last_child()
|
||||
{
|
||||
if(!children().empty())
|
||||
return children().back();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
zshared_node child( int idx )
|
||||
{
|
||||
if(idx>-1 && idx<children().size())
|
||||
return _children[idx];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int add_child( zshared_node node )
|
||||
{
|
||||
_children.push_back( node );
|
||||
node->set_parent( this->shared_from_this() );
|
||||
return int(children().size() - 1);
|
||||
}
|
||||
|
||||
int add_child_at( int idx, zshared_node node )
|
||||
{
|
||||
_children.insert(children().begin() + idx, node );
|
||||
node->set_parent( this->shared_from_this() );
|
||||
return int(children().size() - 1);
|
||||
}
|
||||
|
||||
int own_pos()
|
||||
{
|
||||
auto pos = parent()->child_pos(_id);
|
||||
if( pos == parent()->children().end() )
|
||||
throw std::runtime_error("own_pos: own id not found!");
|
||||
return std::distance( parent()->children().begin(), pos );
|
||||
}
|
||||
|
||||
inline auto child_pos(int node_id)
|
||||
{
|
||||
// fix!
|
||||
return std::find_if(children().begin(), children().end(), match_id(node_id));
|
||||
return children().end();
|
||||
}
|
||||
|
||||
void add_me_at_id( int id )
|
||||
{
|
||||
auto pos = parent()->child_pos( id );
|
||||
if( pos != parent()->children().end() )
|
||||
parent()->_children.insert( pos, this->shared_from_this() );
|
||||
}
|
||||
|
||||
|
||||
void add_me_at_pos( int offset )
|
||||
{
|
||||
auto pos = parent()->children().begin();
|
||||
parent()->_children.insert( pos + offset, this->shared_from_this() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
zshared_node find_child_by_attribute(str_cref attrkey, str_cref attrvalue )
|
||||
{
|
||||
for( auto child : _children )
|
||||
{
|
||||
qDebug() << " --#- " << child->name() << " : " << child->has_attribute( attrkey, attrvalue );
|
||||
if( child->has_attribute( attrkey, attrvalue ))
|
||||
return child;
|
||||
}
|
||||
return zshared_node();
|
||||
}
|
||||
|
||||
|
||||
zshared_node find_child_by_tag_name(str_cref tagname )
|
||||
{
|
||||
for( auto child : _children )
|
||||
{
|
||||
if( child->tag_name() == tagname )
|
||||
return child;
|
||||
}
|
||||
return zshared_node();
|
||||
}
|
||||
|
||||
zshared_node find_child_by_id( int id )
|
||||
{
|
||||
for (auto child : _children )
|
||||
{
|
||||
if (child->_id == id)
|
||||
return child;
|
||||
}
|
||||
return zshared_node();
|
||||
}
|
||||
|
||||
void unlink_child( zshared_node node )
|
||||
{
|
||||
/*
|
||||
* fix!
|
||||
zbasic_node* child = nullptr;
|
||||
auto pos = child_pos(node->_id);
|
||||
if( pos != children().end() )
|
||||
{
|
||||
child = *pos;
|
||||
qDebug() << " --- delete child: _id: " << child->_id;
|
||||
children().erase( pos );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void unlink_self()
|
||||
{
|
||||
parent()->unlink_child( this->shared_from_this() );
|
||||
}
|
||||
|
||||
void dump(int indent = 0) const
|
||||
{
|
||||
|
||||
// fix_me!
|
||||
qDebug() << std::string(indent * 2, ' ').c_str() << this->to_string();
|
||||
//qDebug() << to_string();
|
||||
//qDebug() << '\n';// std::endl;
|
||||
|
||||
if (!children().empty())
|
||||
{
|
||||
for (auto child : _children)
|
||||
{
|
||||
//qDebug() << " --- type: " << typeid(child).name();
|
||||
child.get()->dump( indent + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool for_each_x( T func, int depth = 0 )
|
||||
//bool for_each( auto func ) const
|
||||
{
|
||||
if( !apply( func, depth ) )
|
||||
return false;
|
||||
|
||||
if( !children().empty() )
|
||||
{
|
||||
for( auto child : _children )
|
||||
{
|
||||
if( !child->for_each( func, depth+1 ) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// find ...
|
||||
// depth first ...
|
||||
// by attr
|
||||
// by child
|
||||
// by value
|
||||
// by find( auto xxx )
|
||||
// ...
|
||||
|
||||
};
|
||||
|
||||
|
||||
class zbasic_node_walker
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void begin()
|
||||
{}
|
||||
|
||||
template<class str_t>
|
||||
void for_each_node( zbasic_node<str_t>* node );
|
||||
|
||||
virtual void end()
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} //namespace znode
|
||||
|
||||
|
||||
|
||||
#endif // zplain_node_H
|
123
nodes/znode_factory.h
Normal file
123
nodes/znode_factory.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/***************************************************************************
|
||||
|
||||
source::worx xtree
|
||||
Copyright © 2024-2025 c.holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef ZNODE_FACTORY_H
|
||||
#define ZNODE_FACTORY_H
|
||||
|
||||
#include <pugixml.hpp>
|
||||
#include <znode.h>
|
||||
|
||||
class xtree;
|
||||
|
||||
/*
|
||||
|
||||
nodes: nackt also ungekaspselt?
|
||||
-> children()
|
||||
-> attributes()
|
||||
|
||||
attributes: ja was seid ihr denn? als string gelesen, als string geschrieben, aber dazwischen?
|
||||
|
||||
-> std::variant<bool...> mit enum type{t_bool = 0 ...};
|
||||
-> conversion mit boost::lexical_cast<> bzw. std::to_string() und std::stoi(), std::stod()
|
||||
-> beim parsen konvertieren? contains '.'? is_number?
|
||||
-> betrifft tag_values und tag_attributes
|
||||
-> vorher definieren? attribute 'voltage' == double, oder gar mehr: unit V, double, range
|
||||
-> über xs:double?
|
||||
|
||||
model: muss ich wirklich jeden attibute node einzeln angeben?
|
||||
|
||||
*/
|
||||
namespace znode
|
||||
{
|
||||
template<class str_t>
|
||||
class znode_factory
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
using str_cref = const str_t&;
|
||||
|
||||
using zshared_node = std::shared_ptr<zbasic_node<str_t>>;
|
||||
|
||||
znode_factory() = default;
|
||||
virtual ~znode_factory() = default;
|
||||
|
||||
zshared_node load_tree( const std::string& filename )
|
||||
{
|
||||
|
||||
pugi::xml_document tree_document;
|
||||
// load document
|
||||
pugi::xml_parse_result result = tree_document.load_file( filename.c_str() );
|
||||
if( !result )
|
||||
{
|
||||
throw XQException( "znode_factory::load_tree: parse error: ", result.description() );
|
||||
}
|
||||
|
||||
//MemberFunc func = &znode_factory::process_node;
|
||||
//xtreewalker<znode_factory, MemberFunc> parser(this,func);
|
||||
//_current_depth = -1;
|
||||
//tree_document.traverse(parser);
|
||||
|
||||
//zbasic_node<str_t>* root_node = new zbasic_node<str_t>*("root!");
|
||||
zshared_node root_node = zbasic_node<str_t>::make_node("root!");
|
||||
//T root_node = T::make_node( "root!" );
|
||||
|
||||
// prepare root == model !?
|
||||
pugi::xml_node tmp_node = tree_document.first_child();
|
||||
while(tmp_node)
|
||||
{
|
||||
//qDebug() << " --- znode_factory building: " << tmp_node.name();
|
||||
create_node( tmp_node, root_node );
|
||||
tmp_node = tmp_node.next_sibling();
|
||||
}
|
||||
|
||||
//znode::zmeas_para<QString>* xxx = new znode::zmeas_para<QString>("mookoo!");
|
||||
//xxx->apply_command(42);
|
||||
// _root_node->apply_command(42);
|
||||
//size_t idx = _root_node->add_child( xxx);
|
||||
//qDebug() << " jo: " << _root_node->child(idx)->tag_name();
|
||||
|
||||
return root_node;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void create_node(const pugi::xml_node& xml_node, zshared_node parent)
|
||||
{
|
||||
|
||||
//T* new_node = new T( node.name(), node.child_value(), parent );
|
||||
//parent->add_child( new_node );
|
||||
|
||||
//zbasic_node<str_t>* new_node = new zbasic_node<str_t>( node.name(), node.child_value(), parent );
|
||||
zshared_node new_node = zbasic_node<str_t>::make_node( xml_node.name(), xml_node.child_value(), parent );
|
||||
parent->add_child( new_node );
|
||||
|
||||
if( !xml_node.attributes().empty() )
|
||||
{
|
||||
for (pugi::xml_attribute attr: xml_node.attributes())
|
||||
new_node->set_attribute( attr.name(), attr.value() );
|
||||
}
|
||||
|
||||
if( !xml_node.children().empty() && std::string( xml_node.child_value() ).empty() )
|
||||
{
|
||||
for (pugi::xml_node child : xml_node.children())
|
||||
create_node( child, new_node );
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ZNODE_FACTORY_H
|
33
nodes/znode_id.h
Normal file
33
nodes/znode_id.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef ZNODE_ID_H
|
||||
#define ZNODE_ID_H
|
||||
|
||||
namespace znode
|
||||
{
|
||||
|
||||
struct zid
|
||||
{
|
||||
zid()
|
||||
{
|
||||
static int s_ID{0};
|
||||
|
||||
_id = s_ID++;
|
||||
s_Count++;
|
||||
//qDebug() << " --- con ID: " << _id << " count: " << s_Count;
|
||||
}
|
||||
|
||||
virtual ~zid()
|
||||
{
|
||||
s_Count--;
|
||||
//qDebug() << " --- del ID: " << _id << " count: " << s_Count;
|
||||
}
|
||||
|
||||
static int s_Count;
|
||||
int _id{0};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // ZNODE_ID_H
|
||||
|
124
nodes/znode_iterator.h
Normal file
124
nodes/znode_iterator.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/***************************************************************************
|
||||
|
||||
source::worx xtree
|
||||
Copyright © 2024-2025 c.holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef znode_iterator_H
|
||||
#define znode_iterator_H
|
||||
|
||||
#include <iterator>
|
||||
|
||||
|
||||
|
||||
namespace znode
|
||||
{
|
||||
template<class T>
|
||||
struct znode_iterator
|
||||
{
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = T;
|
||||
using pointer = T*; // or also value_type*
|
||||
using reference = T&; // or also value_type&
|
||||
|
||||
znode_iterator()
|
||||
: _root{},_node{}
|
||||
{}
|
||||
|
||||
znode_iterator(pointer node)
|
||||
: _root{node},_node{node}
|
||||
{}
|
||||
|
||||
void set_node(pointer node)
|
||||
{
|
||||
_root = node;
|
||||
_node = node;
|
||||
}
|
||||
|
||||
pointer get() // const
|
||||
{
|
||||
return _node;
|
||||
}
|
||||
|
||||
int level() // const
|
||||
{
|
||||
return _level;
|
||||
}
|
||||
|
||||
pointer operator->()
|
||||
{
|
||||
return _node;
|
||||
}
|
||||
|
||||
reference operator*()
|
||||
{
|
||||
return *(operator->());
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return _node != nullptr;
|
||||
}
|
||||
|
||||
// Prefix increment
|
||||
znode_iterator& operator++()
|
||||
{
|
||||
if( !_node )
|
||||
return *this;
|
||||
|
||||
// depth first: do we have children?
|
||||
if( _node->has_children() )
|
||||
{
|
||||
_node = _node->first_child().get();
|
||||
_level++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// no children, so we take siblings
|
||||
pointer tmp = _node->sibling().get();
|
||||
pointer nxt = _node->parent().get();
|
||||
|
||||
while( !tmp && nxt )
|
||||
{
|
||||
tmp = nxt->sibling().get();
|
||||
if( nxt == _root )
|
||||
{
|
||||
//qDebug() << " ouch ";
|
||||
_node = nullptr;
|
||||
return *this;
|
||||
}
|
||||
_level--;
|
||||
nxt = nxt->parent().get();
|
||||
}
|
||||
|
||||
_node = tmp;
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
// Postfix increment
|
||||
znode_iterator operator++(int) { znode_iterator tmp = *this; ++(*this); return tmp; }
|
||||
|
||||
friend bool operator== (const znode_iterator& a, const znode_iterator& b) { return a._node == b._node; };
|
||||
friend bool operator!= (const znode_iterator& a, const znode_iterator& b) { return a._node != b._node; };
|
||||
|
||||
protected:
|
||||
|
||||
pointer _root{};
|
||||
pointer _node{};
|
||||
int _level{0};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // znode_iterator_H
|
262
nodes/znode_payload.h
Normal file
262
nodes/znode_payload.h
Normal file
@@ -0,0 +1,262 @@
|
||||
#ifndef ZNODE_PAYLOAD_H
|
||||
#define ZNODE_PAYLOAD_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
//#include <znode_stringmap.h>
|
||||
//#include <znode_attributes.h>
|
||||
|
||||
namespace znode
|
||||
{
|
||||
template<class str_t>
|
||||
class zstringmap : public std::map<str_t,str_t>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
using str_cref = const str_t&;
|
||||
using str_ptr = str_t*;
|
||||
using str_list = std::vector<str_t>;
|
||||
|
||||
using zvalue = str_t; // could be any or variant
|
||||
// __fixme: should this be a vector? or a maptor?
|
||||
//using zattributes = std::map<str_t, zvalue>;
|
||||
using zattributes = zstringmap<str_t>;
|
||||
|
||||
str_cref key_of(str_cref value) const
|
||||
{
|
||||
for( const auto& pair : *this )
|
||||
{
|
||||
if (pair.second == value)
|
||||
return pair.first;
|
||||
}
|
||||
|
||||
static str_t s_dummy;
|
||||
return s_dummy;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class str_t>
|
||||
class zpayload
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
using str_cref = const str_t&;
|
||||
using str_ptr = str_t*;
|
||||
using str_list = std::vector<str_t>;
|
||||
|
||||
using zvalue = str_t; // could be any or variant
|
||||
// __fixme: should this be a vector? or a maptor?
|
||||
//using zattributes = std::map<str_t, zvalue>;
|
||||
using zattributes = zstringmap<str_t>;
|
||||
|
||||
static const str_t cType;// = "Type";
|
||||
static const str_t cName;// = "Name";
|
||||
static const str_t cValue;// = "Value";
|
||||
static const str_t cFriendlyName;
|
||||
|
||||
zpayload( str_cref tag_name )
|
||||
: _tag_name{tag_name}
|
||||
{}
|
||||
|
||||
// ...
|
||||
zpayload( str_cref tag_name, str_cref value )
|
||||
: _tag_name{tag_name}, _value{value}
|
||||
{}
|
||||
|
||||
zpayload( str_cref tag_name, const str_list& attriblist )
|
||||
: zpayload(tag_name)
|
||||
{
|
||||
for( str_cref entry : attriblist )
|
||||
{
|
||||
str_t key_value, data_value;
|
||||
if( xstr_split_by( entry, "=", key_value, data_value) )
|
||||
set_attribute( key_value, data_value );
|
||||
}
|
||||
}
|
||||
|
||||
str_cref tag_name() const
|
||||
{
|
||||
return _tag_name;
|
||||
}
|
||||
|
||||
str_ptr tag_name_ptr()
|
||||
{
|
||||
return &_tag_name;
|
||||
}
|
||||
|
||||
void set_tag_name( str_cref tag_name )
|
||||
{
|
||||
_tag_name = tag_name;
|
||||
}
|
||||
|
||||
str_cref tag_value() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
str_ptr tag_value_ptr()
|
||||
{
|
||||
return &_value;
|
||||
}
|
||||
|
||||
void set_tag_value( str_cref value )
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
str_cref friendly_name() const
|
||||
{
|
||||
return attribute(cFriendlyName);
|
||||
}
|
||||
|
||||
str_ptr friendly_name_ptr()
|
||||
{
|
||||
return &attribute(cFriendlyName);
|
||||
}
|
||||
|
||||
str_cref type() const
|
||||
{
|
||||
return attribute(cType);
|
||||
}
|
||||
|
||||
str_ptr type_ptr() const
|
||||
{
|
||||
return &attribute(cType);
|
||||
}
|
||||
|
||||
void set_type( str_cref type )
|
||||
{
|
||||
set_attribute( cType, type);
|
||||
}
|
||||
|
||||
str_cref name() const
|
||||
{
|
||||
return attribute(cName);
|
||||
}
|
||||
|
||||
str_ptr name_ptr()
|
||||
{
|
||||
return &attribute(cName);
|
||||
}
|
||||
|
||||
void set_name( str_cref name )
|
||||
{
|
||||
set_attribute( cType, name);
|
||||
}
|
||||
|
||||
const zattributes& attributes() const
|
||||
{
|
||||
return _attributes;
|
||||
}
|
||||
|
||||
bool has_attribute(str_cref key ) const
|
||||
{
|
||||
if( xstr_is_empty( key ) )
|
||||
return false;
|
||||
typename zattributes::const_iterator pos = _attributes.find(key);
|
||||
if( pos == _attributes.end() )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_attribute(str_cref key, str_cref value ) const
|
||||
{
|
||||
if( xstr_is_empty( key ) )
|
||||
return false;
|
||||
typename zattributes::const_iterator pos = _attributes.find(key);
|
||||
if( pos == _attributes.end() )
|
||||
return false;
|
||||
if( !xstr_is_empty( value ) )
|
||||
return (*pos).second == value;
|
||||
return true;
|
||||
}
|
||||
|
||||
const zvalue& attribute(str_cref key ) const
|
||||
{
|
||||
if( !xstr_is_empty( key ) )
|
||||
{
|
||||
typename zattributes::const_iterator pos = _attributes.find(key);
|
||||
if (pos != _attributes.end())
|
||||
{
|
||||
const zvalue& result = (*pos).second;
|
||||
if (!xstr_is_empty(result) && result[0] == '@')
|
||||
return attribute( xstr_sub_str(result, 1) );
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return s_dummy_value;
|
||||
}
|
||||
|
||||
const zvalue* attribute_ptr(str_cref key ) const
|
||||
{
|
||||
if( !xstr_is_empty( key ) )
|
||||
{
|
||||
typename zattributes::const_iterator pos = _attributes.find(key);
|
||||
if (pos != _attributes.end())
|
||||
{
|
||||
const zvalue& result = (*pos).second;
|
||||
if (!xstr_is_empty(result) && result[0] == '@')
|
||||
return attribute_ptr( xstr_sub_str(result, 1) );
|
||||
return &result;
|
||||
}
|
||||
}
|
||||
return &s_dummy_value;
|
||||
}
|
||||
|
||||
void set_attribute(str_cref key, zvalue value )
|
||||
{
|
||||
if( !xstr_is_empty( key ) )
|
||||
_attributes[key] = value;
|
||||
}
|
||||
|
||||
// dumper
|
||||
str_t to_string() const
|
||||
{
|
||||
str_t result = '<' +_tag_name +'>';
|
||||
if( !xstr_is_empty(_value) )
|
||||
result += ": " + _value;
|
||||
if( !_attributes.empty() )
|
||||
{
|
||||
result += " [";
|
||||
bool first = true;
|
||||
for (const auto& entry : _attributes)
|
||||
{
|
||||
if(first)
|
||||
{
|
||||
result += entry.first + "=" + entry.second;
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
result += ", " + entry.first + "=" + entry.second;
|
||||
}
|
||||
result += "]";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// forward helpers
|
||||
bool xstr_split_by(str_cref entry, str_cref sep, str_t& key, str_t& value );
|
||||
str_t xstr_sub_str(str_cref entry, int pos) const;
|
||||
bool xstr_is_empty(str_cref key ) const;
|
||||
|
||||
protected:
|
||||
|
||||
str_t _tag_name;
|
||||
str_t _value;
|
||||
zattributes _attributes;
|
||||
|
||||
static zvalue s_dummy_value;
|
||||
|
||||
};
|
||||
|
||||
// init statics
|
||||
template<class str_t>
|
||||
str_t zpayload<str_t>::s_dummy_value;
|
||||
|
||||
}
|
||||
|
||||
#endif // ZNODE_PAYLOAD_H
|
50
nodes/znode_vector.h
Normal file
50
nodes/znode_vector.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef ZNODE_VECTOR_H
|
||||
#define ZNODE_VECTOR_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
//using znode_vector = std::vector<zplain_node*>;
|
||||
template<class T>
|
||||
class znode_vector : public std::vector<T*>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// FIX! implement this!
|
||||
// why delete??
|
||||
znode_vector() = default;
|
||||
znode_vector(const znode_vector&) = delete;
|
||||
znode_vector& operator=(const znode_vector&) = delete;
|
||||
|
||||
|
||||
virtual ~znode_vector()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
znode_vector* clone() const
|
||||
{
|
||||
znode_vector* new_list = new znode_vector;
|
||||
clone_into( *new_list );
|
||||
return new_list;
|
||||
}
|
||||
|
||||
void clone_into( znode_vector& new_list ) const
|
||||
{
|
||||
new_list.clear();
|
||||
for(const auto entry : *this )
|
||||
new_list.push_back( entry->clone() );
|
||||
}
|
||||
|
||||
void clone_from( const znode_vector& src_list )
|
||||
{
|
||||
this->clear();
|
||||
for(const auto entry : src_list )
|
||||
this->push_back( entry->clone() );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // ZNODE_VECTOR_H
|
Reference in New Issue
Block a user