diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp')
-rw-r--r-- | Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp | 169 |
1 files changed, 130 insertions, 39 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp index b9a75fa0588..b4e5ed6f2b4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp @@ -29,107 +29,198 @@ #include <vector> #include "utility.hpp" +class XMLCData; +class XMLComment; +class XMLElement; +class XMLText; class XMLNode { + friend class XMLElement; + + template <typename T> + T* cast (const T* (XMLNode::*func)() const) { + return const_cast<T*>((const_cast<const XMLNode*>(this)->*func)()); + } + public: + XMLNode () =default; + XMLNode (const XMLNode &node) : _next(nullptr) {} + XMLNode (XMLNode &&node) noexcept : _parent(node._parent), _prev(node._prev), _next(std::move(node._next)) {} virtual ~XMLNode () =default; virtual std::unique_ptr<XMLNode> clone () const =0; virtual void clear () =0; virtual std::ostream& write (std::ostream &os) const =0; + virtual const XMLElement* toElement () const {return nullptr;} + virtual const XMLText* toText () const {return nullptr;} + virtual const XMLText* toWSNode () const {return nullptr;} + virtual const XMLComment* toComment () const {return nullptr;} + virtual const XMLCData* toCData () const {return nullptr;} + XMLElement* toElement () {return cast<XMLElement>(&XMLNode::toElement);} + XMLText* toText () {return cast<XMLText>(&XMLNode::toText);} + XMLComment* toComment () {return cast<XMLComment>(&XMLNode::toComment);} + XMLCData* toCData () {return cast<XMLCData>(&XMLNode::toCData);} + XMLNode* parent () const {return _parent;} + XMLNode* prev () const {return _prev;} + XMLNode* next () const {return _next.get();} + + protected: + XMLNode* insertNext (std::unique_ptr<XMLNode> node); + std::unique_ptr<XMLNode> removeNext (); + void parent (XMLNode *p) {_parent = p;} + void prev (XMLNode *p) {_prev = p;} + + private: + XMLNode *_parent=nullptr; ///< pointer to parent node + XMLNode *_prev=nullptr; ///< pointer to preceding sibling + std::unique_ptr<XMLNode> _next; ///< pointer to next sibling (incl. ownership) +}; + + +class XMLNodeIterator { + public: + XMLNodeIterator () =default; + explicit XMLNodeIterator (XMLNode *curr) : _curr(curr) {} + XMLNodeIterator& operator ++ () {_curr = _curr->next(); return *this;} + XMLNodeIterator& operator -- () {_curr = _curr->prev(); return *this;} + XMLNodeIterator operator ++ (int) {auto p=_curr; _curr = _curr->next(); return XMLNodeIterator(p);} + XMLNodeIterator operator -- (int) {auto p=_curr; _curr = _curr->prev(); return XMLNodeIterator(p);} + XMLNode* operator * () {return _curr;} + XMLNode& operator -> () {return *_curr;} + bool operator == (const XMLNodeIterator &it) const {return _curr == it._curr;} + bool operator != (const XMLNodeIterator &it) const {return _curr != it._curr;} + + private: + XMLNode *_curr=nullptr; }; -class XMLElementNode : public XMLNode { +class ConstXMLNodeIterator { + public: + ConstXMLNodeIterator () =default; + explicit ConstXMLNodeIterator (const XMLNode *curr) : _curr(curr) {} + ConstXMLNodeIterator& operator ++ () {_curr = _curr->next(); return *this;} + ConstXMLNodeIterator& operator -- () {_curr = _curr->prev(); return *this;} + ConstXMLNodeIterator operator ++ (int) {auto p=_curr; _curr = _curr->next(); return ConstXMLNodeIterator(p);} + ConstXMLNodeIterator operator -- (int) {auto p=_curr; _curr = _curr->prev(); return ConstXMLNodeIterator(p);} + const XMLNode* operator * () {return _curr;} + const XMLNode& operator -> () {return *_curr;} + bool operator == (const ConstXMLNodeIterator &it) const {return _curr == it._curr;} + bool operator != (const ConstXMLNodeIterator &it) const {return _curr != it._curr;} + + private: + const XMLNode *_curr=nullptr; +}; + + +class XMLElement : public XMLNode { public: struct Attribute { - Attribute (const std::string &nam, const std::string &val) : name(nam), value(val) {} + Attribute (std::string nam, std::string val) : name(std::move(nam)), value(std::move(val)) {} std::string name; std::string value; }; - using ChildList = std::deque<std::unique_ptr<XMLNode>>; + using Attributes = std::vector<Attribute>; + static bool WRITE_NEWLINES; ///< insert line breaks after element tags? public: - XMLElementNode (const std::string &name); - XMLElementNode (const XMLElementNode &node); - XMLElementNode (XMLElementNode &&node); - std::unique_ptr<XMLNode> clone () const override {return util::make_unique<XMLElementNode>(*this);} + explicit XMLElement (std::string name); + XMLElement (const XMLElement &node); + XMLElement (XMLElement &&node) noexcept; + std::unique_ptr<XMLNode> clone () const override {return util::make_unique<XMLElement>(*this);} void clear () override; void addAttribute (const std::string &name, const std::string &value); void addAttribute (const std::string &name, double value); - XMLNode* append (std::unique_ptr<XMLNode> &&child); + void removeAttribute (const std::string &name); + XMLNode* append (std::unique_ptr<XMLNode> child); XMLNode* append (const std::string &str); - XMLNode* prepend (std::unique_ptr<XMLNode> &&child); - void remove (const XMLNode *child); - bool insertAfter (std::unique_ptr<XMLNode> &&child, XMLNode *sibling); - bool insertBefore (std::unique_ptr<XMLNode> &&child, XMLNode *sibling); + XMLNode* prepend (std::unique_ptr<XMLNode> child); + XMLNode* insertAfter (std::unique_ptr<XMLNode> child, XMLNode *sibling); + XMLNode* insertBefore (std::unique_ptr<XMLNode> child, XMLNode *sibling); bool hasAttribute (const std::string &name) const; const char* getAttributeValue (const std::string &name) const; - bool getDescendants (const char *name, const char *attrName, std::vector<XMLElementNode*> &descendants) const; - XMLElementNode* getFirstDescendant (const char *name, const char *attrName, const char *attrValue) const; + bool getDescendants (const char *name, const char *attrName, std::vector<XMLElement*> &descendants) const; + XMLElement* getFirstDescendant (const char *name, const char *attrName, const char *attrValue) const; + XMLNode* firstChild () const {return _firstChild.get();} + XMLNode* lastChild () const {return _lastChild;} std::ostream& write (std::ostream &os) const override; - bool empty () const {return _children.empty();} - const ChildList& children () const {return _children;} - const std::string& getName () const {return _name;} + bool empty () const {return !_firstChild;} + Attributes& attributes () {return _attributes;} + const Attributes& attributes () const {return _attributes;} + XMLNodeIterator begin () {return XMLNodeIterator(_firstChild.get());} + XMLNodeIterator end () {return XMLNodeIterator(nullptr);} + ConstXMLNodeIterator begin () const {return ConstXMLNodeIterator(_firstChild.get());} + ConstXMLNodeIterator end () const {return ConstXMLNodeIterator(nullptr);} + const std::string& name () const {return _name;} + const XMLElement* toElement () const override {return this;} + const Attribute* getAttribute (const std::string &name) const; + + static std::unique_ptr<XMLNode> remove (XMLNode *child); + static XMLElement* wrap (XMLNode *first, XMLNode *last, const std::string &name); + static XMLNode* unwrap (XMLElement *child); + protected: Attribute* getAttribute (const std::string &name); - const Attribute* getAttribute (const std::string &name) const; + XMLNode* insertFirst (std::unique_ptr<XMLNode> child); + XMLNode* insertLast (std::unique_ptr<XMLNode> child); private: std::string _name; // element name (<name a1="v1" .. an="vn">...</name>) std::vector<Attribute> _attributes; - ChildList _children; // child nodes + std::unique_ptr<XMLNode> _firstChild; ///< pointer to first child node (incl. ownership) + XMLNode *_lastChild=nullptr; ///< pointer to last child node }; -class XMLTextNode : public XMLNode { +class XMLText : public XMLNode { public: - XMLTextNode (const std::string &str) : _text(str) {} - XMLTextNode (std::string &&str) : _text(std::move(str)) {} - std::unique_ptr<XMLNode> clone () const override {return util::make_unique<XMLTextNode>(*this);} + explicit XMLText (std::string str) : _text(std::move(str)) {} + std::unique_ptr<XMLNode> clone () const override {return util::make_unique<XMLText>(*this);} void clear () override {_text.clear();} - void append (std::unique_ptr<XMLNode> &&node); - void append (std::unique_ptr<XMLTextNode> &&node); + void append (std::unique_ptr<XMLNode> node); + void append (std::unique_ptr<XMLText> node); void append (const std::string &str); - void prepend (std::unique_ptr<XMLNode> &&node); + void prepend (std::unique_ptr<XMLNode> node); std::ostream& write (std::ostream &os) const override {return os << _text;} const std::string& getText () const {return _text;} + const XMLText* toText () const override {return this;} + const XMLText* toWSNode () const override; private: std::string _text; }; -class XMLCommentNode : public XMLNode { +class XMLComment : public XMLNode { public: - XMLCommentNode (const std::string &str) : _text(str) {} - XMLCommentNode (std::string &&str) : _text(std::move(str)) {} - std::unique_ptr<XMLNode> clone () const override {return util::make_unique<XMLCommentNode>(*this);} + explicit XMLComment (std::string str) : _text(std::move(str)) {} + std::unique_ptr<XMLNode> clone () const override {return util::make_unique<XMLComment>(*this);} void clear () override {_text.clear();} std::ostream& write (std::ostream &os) const override {return os << "<!--" << _text << "-->";} + const XMLComment* toComment () const override {return this;} private: std::string _text; }; -class XMLCDataNode : public XMLNode { +class XMLCData : public XMLNode { public: - XMLCDataNode () =default; - XMLCDataNode (const std::string &d) : _data(d) {} - XMLCDataNode (std::string &&d) : _data(std::move(d)) {} - std::unique_ptr<XMLNode> clone () const override {return util::make_unique<XMLCDataNode>(*this);} + XMLCData () =default; + explicit XMLCData (std::string data) : _data(std::move(data)) {} + std::unique_ptr<XMLNode> clone () const override {return util::make_unique<XMLCData>(*this);} void clear () override {_data.clear();} void append (std::string &&str); std::ostream& write (std::ostream &os) const override; + const XMLCData* toCData () const override {return this;} private: std::string _data; }; -inline std::ostream& operator << (std::ostream &os, const XMLElementNode &node) {return node.write(os);} -inline std::ostream& operator << (std::ostream &os, const XMLTextNode &node) {return node.write(os);} -inline std::ostream& operator << (std::ostream &os, const XMLCommentNode &node) {return node.write(os);} -inline std::ostream& operator << (std::ostream &os, const XMLCDataNode &node) {return node.write(os);} +inline std::ostream& operator << (std::ostream &os, const XMLElement &node) {return node.write(os);} +inline std::ostream& operator << (std::ostream &os, const XMLText &node) {return node.write(os);} +inline std::ostream& operator << (std::ostream &os, const XMLComment &node) {return node.write(os);} +inline std::ostream& operator << (std::ostream &os, const XMLCData &node) {return node.write(os);} #endif |