tibia-client/src/framework/otml/otmlnode.h

216 lines
5.4 KiB
C
Raw Normal View History

2011-07-13 23:12:36 +02:00
#ifndef OTMLNODE_H
#define OTMLNODE_H
2011-08-15 16:06:15 +02:00
#include "declarations.h"
2011-08-14 04:09:11 +02:00
#include "otmlexception.h"
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
class OTMLNode : public std::enable_shared_from_this<OTMLNode>
2011-07-13 23:12:36 +02:00
{
public:
2011-08-14 04:09:11 +02:00
OTMLNode();
virtual ~OTMLNode() { }
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
std::string value() const;
std::string tag() const;
int size() const;
OTMLNodePtr parent() const;
const OTMLNodeList& childNodes() const;
std::string source() const;
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
bool hasTag() const;
bool hasValue() const;
bool hasChildNodes() const;
bool hasChild(const std::string& childTag) const;
bool hasChild(int index) const;
bool isUnique() const;
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
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);
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
/// Same as get but if the child node doesn't exist throws an OTMLException
OTMLNodePtr at(const std::string& childTag);
OTMLNodePtr at(int childIndex);
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
/// Get a child node, if doesn't exists returns nullptr
OTMLNodePtr get(const std::string& childTag) const;
OTMLNodePtr get(int childIndex) const;
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
void addChild(const OTMLNodePtr& newChild);
bool removeChild(const OTMLNodePtr& oldChild);
bool replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild);
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
/// Remove all children
void clear();
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
/// Recursively copy children from another node to this node
void merge(const OTMLNodePtr& node);
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
/// Recursively clone this node into a new one
OTMLNodePtr clone() const;
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
/// Emits this node to a std::string
virtual std::string emit();
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
template<typename T>
T read();
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
template<typename T>
T read(const T& def);
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
template<typename T, typename U>
T readAt(const U& childIdentifier);
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
template<typename T, typename U>
T readAt(const U& childIdentifier, const T& def);
template<typename T>
void write(const T& v);
template<typename T>
void writeAt(const std::string& childTag, const T& v);
template<typename T>
void writeIn(const T& v);
2011-07-13 23:12:36 +02:00
private:
std::string m_tag;
std::string m_value;
2011-08-14 04:09:11 +02:00
std::string m_source;
bool m_unique;
OTMLNodeList m_childNodes;
OTMLNodeWeakPtr m_parent;
2011-07-13 23:12:36 +02:00
};
2011-08-14 04:09:11 +02:00
// templates for reading values
template<typename T>
T OTMLNode::read() {
T v;
if(!from_otmlnode(shared_from_this(), v))
throw OTMLException(shared_from_this(),
2011-08-15 16:06:15 +02:00
fw::mkstr("failed to cast node value to type '", fw::demangle_type<T>(), "'"));
2011-08-14 04:09:11 +02:00
return v;
}
2011-07-13 23:12:36 +02:00
2011-08-14 04:09:11 +02:00
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) {
2011-08-15 16:06:15 +02:00
return fw::cast(node->value(), v);
2011-08-14 04:09:11 +02:00
}
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);
2011-07-13 23:12:36 +02:00
return true;
}
2011-08-14 04:09:11 +02:00
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));
2011-07-13 23:12:36 +02:00
return true;
}
template <typename K, typename T>
2011-08-14 04:09:11 +02:00
bool from_otmlnode(OTMLNodePtr node, std::map<K, T>& m) {
for(int i=0;i<node->size();++i) {
2011-07-13 23:12:36 +02:00
K k;
2011-08-15 16:06:15 +02:00
if(!fw::cast(node->at(i)->tag(), k))
2011-07-13 23:12:36 +02:00
return false;
2011-08-14 04:09:11 +02:00
m[k] = node->at(i)->read<T>();
2011-07-13 23:12:36 +02:00
}
return true;
}
2011-08-14 04:09:11 +02:00
// templates for casting a type to a node
template<typename T>
void to_otmlnode(OTMLNodePtr node, const T& v) {
2011-08-15 16:06:15 +02:00
node->setValue(fw::unsafe_cast<std::string>(v));
2011-07-13 23:12:36 +02:00
}
2011-08-14 04:09:11 +02:00
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);
}
2011-07-13 23:12:36 +02:00
}
2011-08-14 04:09:11 +02:00
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);
}
2011-07-13 23:12:36 +02:00
}
template <typename K, typename T>
2011-08-14 04:09:11 +02:00
void to_otmlnode(OTMLNodePtr node, const std::map<K, T>& m) {
for(auto it = m.begin(); it != m.end(); ++it) {
2011-08-15 16:06:15 +02:00
std::string k = fw::unsafe_cast<std::string>(it->first);
2011-08-14 04:09:11 +02:00
OTMLNodePtr newNode(new OTMLNode);
newNode->setTag(k);
newNode->setUnique();
newNode->write(it->second);
node->addChild(newNode);
2011-07-13 23:12:36 +02:00
}
}
2011-08-14 04:09:11 +02:00
#endif