merge total remake

This commit is contained in:
Eduardo Bart
2011-08-13 23:09:11 -03:00
parent 0af7856475
commit 55862b07ad
253 changed files with 6777 additions and 8463 deletions

View File

@@ -1,260 +1,215 @@
#ifndef OTMLNODE_H
#define OTMLNODE_H
#include <string>
#include <vector>
#include <list>
#include <map>
#include <stdexcept>
#include <typeinfo>
#include "otmldeclarations.h"
#include "otmlexception.h"
#include <util/foreach.h>
#include <util/makestring.h>
#include <util/convert.h>
class OTMLException : public std::runtime_error {
public:
OTMLException(const std::string& what) : std::runtime_error(what) {}
};
class OTMLNode
class OTMLNode : public std::enable_shared_from_this<OTMLNode>
{
public:
typedef std::vector<OTMLNode*> NodeList;
typedef NodeList::iterator iterator;
typedef NodeList::const_iterator const_iterator;
OTMLNode();
virtual ~OTMLNode() { }
OTMLNode(std::string what = "");
~OTMLNode();
std::string value() const;
std::string tag() const;
int size() const;
OTMLNodePtr parent() const;
const OTMLNodeList& childNodes() const;
std::string source() const;
bool hasTag() const { return !m_tag.empty(); }
bool hasChildren() const { return size() > 0; }
bool hasValue() const { return !m_value.empty(); }
bool hasChild(const std::string ctag) const { return at(ctag) != 0; }
bool hasTag() const;
bool hasValue() const;
bool hasChildNodes() const;
bool hasChild(const std::string& childTag) const;
bool hasChild(int index) const;
bool isUnique() const;
void setTag(std::string tag) { m_tag = tag; }
void setLine(int line) { m_line = line; }
void setValue(const std::string& value) { m_value = value; }
void setParent(OTMLNode* parent) { m_parent = parent; }
void setTag(std::string tag);
void setValue(const std::string& value);
void setParent(const OTMLNodePtr& parent);
void setUnique(bool unique = true);
void setSource(const std::string& source);
std::string tag() const { return m_tag; }
int line() const { return m_line; }
int size() const { return m_children.size(); }
OTMLNode* parent() { return m_parent; }
std::string what() const { return (m_parent ? m_parent->what() : m_what); }
/// Same as get but if the child node doesn't exist throws an OTMLException
OTMLNodePtr at(const std::string& childTag);
OTMLNodePtr at(int childIndex);
iterator begin() { return m_children.begin(); }
iterator end() { return m_children.end(); }
const_iterator begin() const { return m_children.begin(); }
const_iterator end() const { return m_children.end(); }
/// Get a child node, if doesn't exists returns nullptr
OTMLNodePtr get(const std::string& childTag) const;
OTMLNodePtr get(int childIndex) const;
OTMLNode* front() const { return at(0); }
OTMLNode* back() const { return at(size()-1); }
void addChild(const OTMLNodePtr& newChild);
bool removeChild(const OTMLNodePtr& oldChild);
bool replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild);
OTMLNode* at(const std::string& ctag) const;
OTMLNode* at(int pos) const;
OTMLNode *atPath(const std::string& path) const;
/// Remove all children
void clear();
OTMLNode* createNode(std::string tag = "");
void addNode(OTMLNode* node);
bool removeNode(OTMLNode* node);
/// Recursively copy children from another node to this node
void merge(const OTMLNodePtr& node);
std::string generateErrorMessage(const std::string& message) const;
void throwError(const std::string& message) const;
/// Recursively clone this node into a new one
OTMLNodePtr clone() const;
std::string value(const std::string& def = "") const { return (m_value.empty() ? def : m_value); }
std::string valueAt(const std::string ctag, const std::string& def = "") const {
OTMLNode* c = at(ctag);
return (c ? c->value() : def);
}
std::string valueAt(int pos, const std::string& def = "") const {
OTMLNode* n = at(pos);
return (n ? n->value() : def);
}
std::string valueAtPath(const std::string path, const std::string& def = "") const {
OTMLNode* c = atPath(path);
return (c ? c->value() : def);
}
/// Emits this node to a std::string
virtual std::string emit();
// read into memory
template <typename T>
void read(T* v) const {
if(!(*this >> *v))
throwError(make_string("failed to cast node value to type ", std::string(typeid(T).name())));
}
template<typename T>
T read();
template <typename T>
bool readAt(const std::string& ctag, T* v) const {
if(OTMLNode* node = at(ctag)) {
node->read<T>(v);
return true;
}
return false;
}
template<typename T>
T read(const T& def);
template <typename T>
bool readAt(int pos, T* v) const {
if(OTMLNode* node = at(pos)) {
node->read<T>(v);
return true;
}
return false;
}
template<typename T, typename U>
T readAt(const U& childIdentifier);
template <typename T>
bool readAtPath(const std::string& ctag, T* v) const {
if(OTMLNode* node = atPath(ctag)) {
node->read<T>(v);
return true;
}
return false;
}
template<typename T, typename U>
T readAt(const U& childIdentifier, const T& def);
// read returning the result
template <typename T>
T read() const { T v; read<T>(&v); return v;}
template<typename T>
void write(const T& v);
template <typename T>
T readAt(const std::string& ctag) const {
T v;
if(!readAt(ctag, &v))
throwError(make_string("child node \'", ctag, "\' not found"));
return v;
}
template<typename T>
void writeAt(const std::string& childTag, const T& v);
template <typename T>
T readAt(int pos) const {
T v;
if(!readAt(pos, &v))
throwError(make_string("child node at pos ", pos, " not found"));
return v;
}
template <typename T>
T readAtPath(const std::string& ctag) const {
T v;
if(!readAtPath(ctag, &v))
throwError(make_string("child node in path \'", ctag, "\' not found"));
return v;
}
// read with default supplied
template <typename T>
T readAt(const std::string& ctag, const T& def) const {
OTMLNode* c = at(ctag);
return (c ? c->read<T>() : def);
}
template <typename T>
T readAt(int pos, const T& def) const {
OTMLNode* c = at(pos);
return (c ? c->read<T>() : def);
}
template <typename T>
T readAtPath(const std::string& path, const T& def) const {
OTMLNode* c = atPath(path);
return (c ? c->read<T>() : def);
}
// writing
template <typename T>
void write(T v) {
if(!(*this << v))
throwError(make_string("failed to cast to string node value of type ", typeid(T).name()));
}
template <typename T>
void writeIn(int pos, T v) {
OTMLNode* c;
while(!at(pos))
c = createNode();
c->write<T>(v);
}
template <typename T>
void writeIn(const std::string& ctag, T v) {
OTMLNode* c = at(ctag);
if(!c)
c = createNode(ctag);
c->write<T>(v);
}
template<typename T>
void writeIn(const T& v);
private:
OTMLNode* m_parent;
int m_line;
std::string m_what;
NodeList m_children;
std::string m_tag;
std::string m_value;
std::string m_source;
bool m_unique;
OTMLNodeList m_childNodes;
OTMLNodeWeakPtr m_parent;
};
// read operators
template <typename T>
bool operator >> (const OTMLNode& node, T& v) { return safe_convert(node.value(), v); }
// templates for reading values
template<typename T>
T OTMLNode::read() {
T v;
if(!from_otmlnode(shared_from_this(), v))
throw OTMLException(shared_from_this(),
aux::make_string("failed to cast node value to type '", aux::demangle_type<T>(), "'"));
return v;
}
template <typename T>
bool operator >> (const OTMLNode& node, std::vector<T>& v) {
v.resize(node.size());
for(unsigned i=0;i<node.size();++i)
v[i] = node.readAt<T>(i);
template<typename T>
T OTMLNode::read(const T& def) {
if(hasValue())
return read<T>();
return def;
}
template<typename T, typename U>
T OTMLNode::readAt(const U& childIdentifier) {
OTMLNodePtr child = at(childIdentifier);
return child->read<T>();
}
template<typename T, typename U>
T OTMLNode::readAt(const U& childIdentifier, const T& def) {
OTMLNodePtr child = get(childIdentifier);
if(!child)
return def;
return child->read<T>(def);
}
// templates for writing values
template<typename T>
void OTMLNode::write(const T& v) {
to_otmlnode(shared_from_this(), v);
}
template<typename T>
void OTMLNode::writeAt(const std::string& childTag, const T& v) {
OTMLNodePtr child = get(childTag);
bool created = false;
if(!child) {
child = OTMLNodePtr(new OTMLNode);
child->setTag(childTag);
child->setUnique();
created = true;
}
child->write<T>(v);
if(created)
addChild(child);
}
template<typename T>
void OTMLNode::writeIn(const T& v) {
OTMLNodePtr child = OTMLNodePtr(new OTMLNode);
child->write<T>(v);
addChild(child);
}
// templates for casting a node to another type
template<typename T>
bool from_otmlnode(OTMLNodePtr node, T& v) {
return aux::cast(node->value(), v);
}
template<typename T>
bool from_otmlnode(OTMLNodePtr node, std::vector<T>& v) {
v.resize(node->size());
for(unsigned i=0;i<node->size();++i)
v[i] = node->readAt<T>(i);
return true;
}
template <typename T>
bool operator >> (const OTMLNode& node, std::list<T>& v) {
for(unsigned i=0;i<node.size();++i)
v.push_back(node.readAt<T>(i));
template<typename T>
bool from_otmlnode(OTMLNodePtr node, std::list<T>& v) {
for(unsigned i=0;i<node->size();++i)
v.push_back(node->readAt<T>(i));
return true;
}
template <typename K, typename T>
bool operator >> (const OTMLNode& node, std::map<K, T>& m) {
for(int i=0;i<node.size();++i) {
bool from_otmlnode(OTMLNodePtr node, std::map<K, T>& m) {
for(int i=0;i<node->size();++i) {
K k;
if(!safe_convert(node.at(i)->tag(), k))
if(!aux::cast(node->at(i)->tag(), k))
return false;
m[k] = node.at(i)->read<T>();
m[k] = node->at(i)->read<T>();
}
return true;
}
// write operators
template <typename T>
bool operator << (OTMLNode& node, const T& v) {
std::string out;
if(!safe_convert(v, out))
return false;
node.setValue(out);
return true;
// templates for casting a type to a node
template<typename T>
void to_otmlnode(OTMLNodePtr node, const T& v) {
node->setValue(aux::unsafe_cast<std::string>(v));
}
template <typename T>
bool operator << (OTMLNode& node, const std::vector<T>& v) {
for(unsigned i=0;i<v.size();++i)
node.createNode()->write(v[i]);
return true;
template<typename T>
void to_otmlnode(OTMLNodePtr node, const std::vector<T>& v) {
for(unsigned i=0;i<v.size();++i) {
OTMLNodePtr newNode(new OTMLNode);
newNode->write(v[i]);
node->addChild(newNode);
}
}
template <typename T>
bool operator << (OTMLNode& node, const std::list<T>& v) {
for(unsigned i=0;i<v.size();++i)
node.createNode()->write(v[i]);
return true;
template<typename T>
void to_otmlnode(OTMLNodePtr node, const std::list<T>& v) {
for(unsigned i=0;i<v.size();++i) {
OTMLNodePtr newNode(new OTMLNode);
newNode->write(v[i]);
node->addChild(newNode);
}
}
template <typename K, typename T>
bool operator << (OTMLNode& node, const std::map<K, T>& m) {
typename std::map<K, T>::const_iterator it;
for(it = m.begin(); it != m.end(); ++it) {
std::string k;
if(!safe_convert(it->first, k))
return false;
node.createNode(k)->write(it->second);
void to_otmlnode(OTMLNodePtr node, const std::map<K, T>& m) {
for(auto it = m.begin(); it != m.end(); ++it) {
std::string k = aux::unsafe_cast<std::string>(it->first);
OTMLNodePtr newNode(new OTMLNode);
newNode->setTag(k);
newNode->setUnique();
newNode->write(it->second);
node->addChild(newNode);
}
return true;
}
#include "otmlnodeext.h"
#endif // OTMLNODE_H
#endif