#ifndef OTMLNODE_H #define OTMLNODE_H #include #include #include #include #include #include #include #include #include class OTMLException : public std::runtime_error { public: OTMLException(const std::string& what) : std::runtime_error(what) {} }; class OTMLNode { public: typedef std::vector NodeList; typedef NodeList::iterator iterator; typedef NodeList::const_iterator const_iterator; OTMLNode(std::string what = ""); ~OTMLNode(); 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; } 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; } 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); } 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(); } OTMLNode* front() const { return at(0); } OTMLNode* back() const { return at(size()-1); } OTMLNode* at(const std::string& ctag) const; OTMLNode* at(int pos) const; OTMLNode *atPath(const std::string& path) const; OTMLNode* createNode(std::string tag = ""); void addNode(OTMLNode* node); bool removeNode(OTMLNode* node); std::string generateErrorMessage(const std::string& message) const; void throwError(const std::string& message) 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); } // read into memory template void read(T* v) const { if(!(*this >> *v)) throwError(make_string("failed to cast node value to type ", std::string(typeid(T).name()))); } template bool readAt(const std::string& ctag, T* v) const { if(OTMLNode* node = at(ctag)) { node->read(v); return true; } return false; } template bool readAt(int pos, T* v) const { if(OTMLNode* node = at(pos)) { node->read(v); return true; } return false; } template bool readAtPath(const std::string& ctag, T* v) const { if(OTMLNode* node = atPath(ctag)) { node->read(v); return true; } return false; } // read returning the result template T read() const { T v; read(&v); return v;} template T readAt(const std::string& ctag) const { T v; if(!readAt(ctag, &v)) throwError(make_string("child node \'", ctag, "\' not found")); return v; } template T readAt(int pos) const { T v; if(!readAt(pos, &v)) throwError(make_string("child node at pos ", pos, " not found")); return v; } template 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 T readAt(const std::string& ctag, const T& def) const { OTMLNode* c = at(ctag); return (c ? c->read() : def); } template T readAt(int pos, const T& def) const { OTMLNode* c = at(pos); return (c ? c->read() : def); } template T readAtPath(const std::string& path, const T& def) const { OTMLNode* c = atPath(path); return (c ? c->read() : def); } // writing template void write(T v) { if(!(*this << v)) throwError(make_string("failed to cast to string node value of type ", typeid(T).name())); } template void writeIn(int pos, T v) { OTMLNode* c; while(!at(pos)) c = createNode(); c->write(v); } template void writeIn(const std::string& ctag, T v) { OTMLNode* c = at(ctag); if(!c) c = createNode(ctag); c->write(v); } private: OTMLNode* m_parent; int m_line; std::string m_what; NodeList m_children; std::string m_tag; std::string m_value; }; // read operators template bool operator >> (const OTMLNode& node, T& v) { return safe_convert(node.value(), v); } template bool operator >> (const OTMLNode& node, std::vector& v) { v.resize(node.size()); for(unsigned i=0;i(i); return true; } template bool operator >> (const OTMLNode& node, std::list& v) { for(unsigned i=0;i(i)); return true; } template bool operator >> (const OTMLNode& node, std::map& m) { for(int i=0;itag(), k)) return false; m[k] = node.at(i)->read(); } return true; } // write operators template bool operator << (OTMLNode& node, const T& v) { std::string out; if(!safe_convert(v, out)) return false; node.setValue(out); return true; } template bool operator << (OTMLNode& node, const std::vector& v) { for(unsigned i=0;iwrite(v[i]); return true; } template bool operator << (OTMLNode& node, const std::list& v) { for(unsigned i=0;iwrite(v[i]); return true; } template bool operator << (OTMLNode& node, const std::map& m) { typename std::map::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); } return true; } #include "otmlnodeext.h" #endif // OTMLNODE_H