1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* 3 * This file is part of the libe-book project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 */ 9 10 #ifndef XMLTREENODE_H_INCLUDED 11 #define XMLTREENODE_H_INCLUDED 12 13 #include <deque> 14 #include <string> 15 #include <utility> 16 17 #include <boost/intrusive_ptr.hpp> 18 19 #include "libebook_libcss.h" 20 21 namespace libebook 22 { 23 24 struct XMLTreeNode; 25 typedef boost::intrusive_ptr<XMLTreeNode> XMLTreeNodePtr_t; 26 27 struct XMLTreeNode 28 { 29 enum NodeType 30 { 31 NODE_TYPE_DOCUMENT = 1 << 1, 32 NODE_TYPE_ELEMENT = 1 << 2, 33 NODE_TYPE_TEXT = 1 << 3, 34 NODE_TYPE_COMMENT = 1 << 4, 35 NODE_TYPE_DOCTYPE = 1 << 5 36 }; 37 38 struct QName 39 { 40 LWCStringPtr_t name; 41 LWCStringPtr_t ns; 42 43 QName(); 44 explicit QName(const LWCStringPtr_t &name, const LWCStringPtr_t &ns = LWCStringPtr_t()); 45 }; 46 47 typedef std::pair<QName, QName> LinkId_t; 48 49 struct Configuration 50 { 51 bool caseless; 52 53 std::deque<QName> classes; //< A list of attributes representing a "class". 54 std::deque<QName> ids; //< a list of attributes representing an "ID". 55 std::deque<QName> langs; //< a list of attributes representing a "lang". 56 57 /** A list of element / attribute pairs representing a "link". 58 * 59 * Either element or attribute name can be empty, matching 60 * anything. E.g., xlink:href attribute is always a link. 61 */ 62 std::deque<LinkId_t> links; 63 64 explicit Configuration(bool caseless_ = false); 65 }; 66 67 typedef std::shared_ptr<Configuration> ConfigurationPtr_t; 68 69 struct ElementData 70 { 71 QName qname; 72 mutable int id; 73 mutable bool idSet; 74 75 ElementData(); 76 explicit ElementData(const LWCStringPtr_t &name, const LWCStringPtr_t &ns = LWCStringPtr_t()); 77 }; 78 79 struct AttributeData 80 { 81 QName qname; 82 LWCStringPtr_t value; 83 mutable int id; 84 mutable bool idSet; 85 86 AttributeData(); 87 AttributeData(const LWCStringPtr_t &name, const LWCStringPtr_t &ns, const LWCStringPtr_t &val); 88 AttributeData(const LWCStringPtr_t &name, const LWCStringPtr_t &val); 89 }; 90 91 public: 92 explicit XMLTreeNode(NodeType nodeType, const ConfigurationPtr_t &config = ConfigurationPtr_t()); 93 ~XMLTreeNode(); 94 95 NodeType type; 96 ConfigurationPtr_t configuration; 97 98 ElementData self; 99 std::deque<AttributeData> attributes; 100 std::string text; 101 102 XMLTreeNodePtr_t parent; 103 // siblings 104 XMLTreeNodePtr_t prev; 105 XMLTreeNodePtr_t next; 106 // children 107 XMLTreeNodePtr_t first; 108 XMLTreeNodePtr_t last; 109 110 size_t elements; 111 112 mutable int refcount; 113 114 XMLTreeNodePtr_t clone(bool deep = false) const; 115 116 XMLTreeNodePtr_t appendChild(const XMLTreeNodePtr_t &child); 117 XMLTreeNodePtr_t insertChildBefore(const XMLTreeNodePtr_t &child, const XMLTreeNodePtr_t &selected); 118 void removeChild(const XMLTreeNodePtr_t &child); 119 void transferChildren(const XMLTreeNodePtr_t &newParent); 120 121 void addAttributes(const std::deque<AttributeData> &attrs); 122 123 bool hasChildren(bool ignoreText = false) const; 124 125 private: 126 // disable copying 127 XMLTreeNode(const XMLTreeNode &); 128 XMLTreeNode &operator=(const XMLTreeNode &); 129 }; 130 131 bool operator==(const XMLTreeNode::QName &lhs, const XMLTreeNode::QName &rhs); 132 bool operator!=(const XMLTreeNode::QName &lhs, const XMLTreeNode::QName &rhs); 133 bool caselessEqual(const XMLTreeNode::QName &lhs, const XMLTreeNode::QName &rhs); 134 135 bool operator==(const XMLTreeNode::AttributeData &lhs, const XMLTreeNode::AttributeData &rhs); 136 bool operator!=(const XMLTreeNode::AttributeData &lhs, const XMLTreeNode::AttributeData &rhs); 137 138 bool operator==(const XMLTreeNode::ElementData &lhs, const XMLTreeNode::ElementData &rhs); 139 bool operator!=(const XMLTreeNode::ElementData &lhs, const XMLTreeNode::ElementData &rhs); 140 141 void intrusive_ptr_add_ref(XMLTreeNode *p); 142 void intrusive_ptr_release(XMLTreeNode *p); 143 144 } 145 146 #endif // XMLTREENODE_H_INCLUDED 147 148 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */ 149