1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2019 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtXml module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 #ifndef QDOM_P_H 40 #define QDOM_P_H 41 42 #include "qdom.h" 43 44 #include <qglobal.h> 45 #include <qhash.h> 46 #include <qstring.h> 47 #include <qlist.h> 48 #include <qxml.h> 49 50 QT_BEGIN_NAMESPACE 51 52 // 53 // W A R N I N G 54 // ------------- 55 // 56 // This file is not part of the Qt API. It exists for the convenience of 57 // qxml.cpp and qdom.cpp. This header file may change from version to version without 58 // notice, or even be removed. 59 // 60 // We mean it. 61 // 62 63 /************************************************************** 64 * 65 * Private class declerations 66 * 67 **************************************************************/ 68 69 class QDomImplementationPrivate 70 { 71 public: QDomImplementationPrivate()72 inline QDomImplementationPrivate() {} 73 74 QDomImplementationPrivate *clone(); 75 QAtomicInt ref; 76 static QDomImplementation::InvalidDataPolicy invalidDataPolicy; 77 }; 78 79 class QDomNodePrivate 80 { 81 public: 82 QDomNodePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr); 83 QDomNodePrivate(QDomNodePrivate *n, bool deep); 84 virtual ~QDomNodePrivate(); 85 nodeName()86 QString nodeName() const { return name; } nodeValue()87 QString nodeValue() const { return value; } setNodeValue(const QString & v)88 virtual void setNodeValue(const QString &v) { value = v; } 89 90 QDomDocumentPrivate *ownerDocument(); 91 void setOwnerDocument(QDomDocumentPrivate *doc); 92 93 virtual QDomNodePrivate *insertBefore(QDomNodePrivate *newChild, QDomNodePrivate *refChild); 94 virtual QDomNodePrivate *insertAfter(QDomNodePrivate *newChild, QDomNodePrivate *refChild); 95 virtual QDomNodePrivate *replaceChild(QDomNodePrivate *newChild, QDomNodePrivate *oldChild); 96 virtual QDomNodePrivate *removeChild(QDomNodePrivate *oldChild); 97 virtual QDomNodePrivate *appendChild(QDomNodePrivate *newChild); 98 99 QDomNodePrivate *namedItem(const QString &name); 100 101 virtual QDomNodePrivate *cloneNode(bool deep = true); 102 virtual void normalize(); 103 virtual void clear(); 104 parent()105 inline QDomNodePrivate *parent() const { return hasParent ? ownerNode : nullptr; } setParent(QDomNodePrivate * p)106 inline void setParent(QDomNodePrivate *p) 107 { 108 ownerNode = p; 109 hasParent = true; 110 } 111 setNoParent()112 void setNoParent() 113 { 114 ownerNode = hasParent ? (QDomNodePrivate *)ownerDocument() : nullptr; 115 hasParent = false; 116 } 117 118 // Dynamic cast isAttr()119 bool isAttr() const { return nodeType() == QDomNode::AttributeNode; } isCDATASection()120 bool isCDATASection() const { return nodeType() == QDomNode::CDATASectionNode; } isDocumentFragment()121 bool isDocumentFragment() const { return nodeType() == QDomNode::DocumentFragmentNode; } isDocument()122 bool isDocument() const { return nodeType() == QDomNode::DocumentNode; } isDocumentType()123 bool isDocumentType() const { return nodeType() == QDomNode::DocumentTypeNode; } isElement()124 bool isElement() const { return nodeType() == QDomNode::ElementNode; } isEntityReference()125 bool isEntityReference() const { return nodeType() == QDomNode::EntityReferenceNode; } isText()126 bool isText() const 127 { 128 const QDomNode::NodeType nt = nodeType(); 129 return (nt == QDomNode::TextNode) || (nt == QDomNode::CDATASectionNode); 130 } isEntity()131 bool isEntity() const { return nodeType() == QDomNode::EntityNode; } isNotation()132 bool isNotation() const { return nodeType() == QDomNode::NotationNode; } isProcessingInstruction()133 bool isProcessingInstruction() const 134 { 135 return nodeType() == QDomNode::ProcessingInstructionNode; 136 } isCharacterData()137 bool isCharacterData() const 138 { 139 const QDomNode::NodeType nt = nodeType(); 140 return (nt == QDomNode::CharacterDataNode) || (nt == QDomNode::TextNode) 141 || (nt == QDomNode::CommentNode); 142 } isComment()143 bool isComment() const { return nodeType() == QDomNode::CommentNode; } 144 nodeType()145 virtual QDomNode::NodeType nodeType() const { return QDomNode::BaseNode; } 146 147 virtual void save(QTextStream &, int, int) const; 148 149 void setLocation(int lineNumber, int columnNumber); 150 151 // Variables 152 QAtomicInt ref; 153 QDomNodePrivate *prev; 154 QDomNodePrivate *next; 155 QDomNodePrivate *ownerNode; // either the node's parent or the node's owner document 156 QDomNodePrivate *first; 157 QDomNodePrivate *last; 158 159 QString name; // this is the local name if prefix != null 160 QString value; 161 QString prefix; // set this only for ElementNode and AttributeNode 162 QString namespaceURI; // set this only for ElementNode and AttributeNode 163 bool createdWithDom1Interface : 1; 164 bool hasParent : 1; 165 166 int lineNumber; 167 int columnNumber; 168 }; 169 170 class QDomNodeListPrivate 171 { 172 public: 173 QDomNodeListPrivate(QDomNodePrivate *); 174 QDomNodeListPrivate(QDomNodePrivate *, const QString &); 175 QDomNodeListPrivate(QDomNodePrivate *, const QString &, const QString &); 176 ~QDomNodeListPrivate(); 177 178 bool operator==(const QDomNodeListPrivate &) const; 179 bool operator!=(const QDomNodeListPrivate &) const; 180 181 void createList(); 182 QDomNodePrivate *item(int index); 183 int length() const; 184 185 QAtomicInt ref; 186 /* 187 This list contains the children of this node. 188 */ 189 QDomNodePrivate *node_impl; 190 QString tagname; 191 QString nsURI; 192 QList<QDomNodePrivate *> list; 193 long timestamp; 194 }; 195 196 class QDomNamedNodeMapPrivate 197 { 198 public: 199 QDomNamedNodeMapPrivate(QDomNodePrivate *); 200 ~QDomNamedNodeMapPrivate(); 201 202 QDomNodePrivate *namedItem(const QString &name) const; 203 QDomNodePrivate *namedItemNS(const QString &nsURI, const QString &localName) const; 204 QDomNodePrivate *setNamedItem(QDomNodePrivate *arg); 205 QDomNodePrivate *setNamedItemNS(QDomNodePrivate *arg); 206 QDomNodePrivate *removeNamedItem(const QString &name); 207 QDomNodePrivate *item(int index) const; 208 int length() const; 209 bool contains(const QString &name) const; 210 bool containsNS(const QString &nsURI, const QString &localName) const; 211 212 /** 213 * Remove all children from the map. 214 */ 215 void clearMap(); isReadOnly()216 bool isReadOnly() { return readonly; } setReadOnly(bool r)217 void setReadOnly(bool r) { readonly = r; } isAppendToParent()218 bool isAppendToParent() { return appendToParent; } 219 /** 220 * If true, then the node will redirect insert/remove calls 221 * to its parent by calling QDomNodePrivate::appendChild or removeChild. 222 * In addition the map won't increase or decrease the reference count 223 * of the nodes it contains. 224 * 225 * By default this value is false and the map will handle reference counting 226 * by itself. 227 */ setAppendToParent(bool b)228 void setAppendToParent(bool b) { appendToParent = b; } 229 230 /** 231 * Creates a copy of the map. It is a deep copy 232 * that means that all children are cloned. 233 */ 234 QDomNamedNodeMapPrivate *clone(QDomNodePrivate *parent); 235 236 // Variables 237 QAtomicInt ref; 238 QMultiHash<QString, QDomNodePrivate *> map; 239 QDomNodePrivate *parent; 240 bool readonly; 241 bool appendToParent; 242 }; 243 244 class QDomDocumentTypePrivate : public QDomNodePrivate 245 { 246 public: 247 QDomDocumentTypePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr); 248 QDomDocumentTypePrivate(QDomDocumentTypePrivate *n, bool deep); 249 ~QDomDocumentTypePrivate(); 250 void init(); 251 252 // Reimplemented from QDomNodePrivate 253 QDomNodePrivate *cloneNode(bool deep = true) override; 254 QDomNodePrivate *insertBefore(QDomNodePrivate *newChild, QDomNodePrivate *refChild) override; 255 QDomNodePrivate *insertAfter(QDomNodePrivate *newChild, QDomNodePrivate *refChild) override; 256 QDomNodePrivate *replaceChild(QDomNodePrivate *newChild, QDomNodePrivate *oldChild) override; 257 QDomNodePrivate *removeChild(QDomNodePrivate *oldChild) override; 258 QDomNodePrivate *appendChild(QDomNodePrivate *newChild) override; 259 nodeType()260 QDomNode::NodeType nodeType() const override { return QDomNode::DocumentTypeNode; } 261 262 void save(QTextStream &s, int, int) const override; 263 264 // Variables 265 QDomNamedNodeMapPrivate *entities; 266 QDomNamedNodeMapPrivate *notations; 267 QString publicId; 268 QString systemId; 269 QString internalSubset; 270 }; 271 272 class QDomDocumentFragmentPrivate : public QDomNodePrivate 273 { 274 public: 275 QDomDocumentFragmentPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr); 276 QDomDocumentFragmentPrivate(QDomNodePrivate *n, bool deep); 277 278 // Reimplemented from QDomNodePrivate 279 virtual QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()280 QDomNode::NodeType nodeType() const override { return QDomNode::DocumentFragmentNode; } 281 }; 282 283 class QDomCharacterDataPrivate : public QDomNodePrivate 284 { 285 public: 286 QDomCharacterDataPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &data); 287 QDomCharacterDataPrivate(QDomCharacterDataPrivate *n, bool deep); 288 289 int dataLength() const; 290 QString substringData(unsigned long offset, unsigned long count) const; 291 void appendData(const QString &arg); 292 void insertData(unsigned long offset, const QString &arg); 293 void deleteData(unsigned long offset, unsigned long count); 294 void replaceData(unsigned long offset, unsigned long count, const QString &arg); 295 296 // Reimplemented from QDomNodePrivate nodeType()297 QDomNode::NodeType nodeType() const override { return QDomNode::CharacterDataNode; } 298 QDomNodePrivate *cloneNode(bool deep = true) override; 299 }; 300 301 class QDomTextPrivate : public QDomCharacterDataPrivate 302 { 303 public: 304 QDomTextPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val); 305 QDomTextPrivate(QDomTextPrivate *n, bool deep); 306 307 QDomTextPrivate *splitText(int offset); 308 309 // Reimplemented from QDomNodePrivate 310 QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()311 QDomNode::NodeType nodeType() const override { return QDomNode::TextNode; } 312 virtual void save(QTextStream &s, int, int) const override; 313 }; 314 315 class QDomAttrPrivate : public QDomNodePrivate 316 { 317 public: 318 QDomAttrPrivate(QDomDocumentPrivate *, QDomNodePrivate *, const QString &name); 319 QDomAttrPrivate(QDomDocumentPrivate *, QDomNodePrivate *, const QString &nsURI, 320 const QString &qName); 321 QDomAttrPrivate(QDomAttrPrivate *n, bool deep); 322 323 bool specified() const; 324 325 // Reimplemented from QDomNodePrivate 326 void setNodeValue(const QString &v) override; 327 QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()328 QDomNode::NodeType nodeType() const override { return QDomNode::AttributeNode; } 329 virtual void save(QTextStream &s, int, int) const override; 330 331 // Variables 332 bool m_specified; 333 }; 334 335 class QDomElementPrivate : public QDomNodePrivate 336 { 337 public: 338 QDomElementPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name); 339 QDomElementPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &nsURI, 340 const QString &qName); 341 QDomElementPrivate(QDomElementPrivate *n, bool deep); 342 ~QDomElementPrivate(); 343 344 QString attribute(const QString &name, const QString &defValue) const; 345 QString attributeNS(const QString &nsURI, const QString &localName, 346 const QString &defValue) const; 347 void setAttribute(const QString &name, const QString &value); 348 void setAttributeNS(const QString &nsURI, const QString &qName, const QString &newValue); 349 void removeAttribute(const QString &name); 350 QDomAttrPrivate *attributeNode(const QString &name); 351 QDomAttrPrivate *attributeNodeNS(const QString &nsURI, const QString &localName); 352 QDomAttrPrivate *setAttributeNode(QDomAttrPrivate *newAttr); 353 QDomAttrPrivate *setAttributeNodeNS(QDomAttrPrivate *newAttr); 354 QDomAttrPrivate *removeAttributeNode(QDomAttrPrivate *oldAttr); 355 bool hasAttribute(const QString &name); 356 bool hasAttributeNS(const QString &nsURI, const QString &localName); 357 358 QString text(); 359 360 // Reimplemented from QDomNodePrivate attributes()361 QDomNamedNodeMapPrivate *attributes() { return m_attr; } hasAttributes()362 bool hasAttributes() { return (m_attr->length() > 0); } nodeType()363 QDomNode::NodeType nodeType() const override { return QDomNode::ElementNode; } 364 QDomNodePrivate *cloneNode(bool deep = true) override; 365 virtual void save(QTextStream &s, int, int) const override; 366 367 // Variables 368 QDomNamedNodeMapPrivate *m_attr; 369 }; 370 371 class QDomCommentPrivate : public QDomCharacterDataPrivate 372 { 373 public: 374 QDomCommentPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val); 375 QDomCommentPrivate(QDomCommentPrivate *n, bool deep); 376 377 // Reimplemented from QDomNodePrivate 378 QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()379 QDomNode::NodeType nodeType() const override { return QDomNode::CommentNode; } 380 virtual void save(QTextStream &s, int, int) const override; 381 }; 382 383 class QDomCDATASectionPrivate : public QDomTextPrivate 384 { 385 public: 386 QDomCDATASectionPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val); 387 QDomCDATASectionPrivate(QDomCDATASectionPrivate *n, bool deep); 388 389 // Reimplemented from QDomNodePrivate 390 QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()391 QDomNode::NodeType nodeType() const override { return QDomNode::CDATASectionNode; } 392 virtual void save(QTextStream &s, int, int) const override; 393 }; 394 395 class QDomNotationPrivate : public QDomNodePrivate 396 { 397 public: 398 QDomNotationPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name, 399 const QString &pub, const QString &sys); 400 QDomNotationPrivate(QDomNotationPrivate *n, bool deep); 401 402 // Reimplemented from QDomNodePrivate 403 QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()404 QDomNode::NodeType nodeType() const override { return QDomNode::NotationNode; } 405 virtual void save(QTextStream &s, int, int) const override; 406 407 // Variables 408 QString m_sys; 409 QString m_pub; 410 }; 411 412 class QDomEntityPrivate : public QDomNodePrivate 413 { 414 public: 415 QDomEntityPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name, 416 const QString &pub, const QString &sys, const QString ¬ation); 417 QDomEntityPrivate(QDomEntityPrivate *n, bool deep); 418 419 // Reimplemented from QDomNodePrivate 420 QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()421 QDomNode::NodeType nodeType() const override { return QDomNode::EntityNode; } 422 virtual void save(QTextStream &s, int, int) const override; 423 424 // Variables 425 QString m_sys; 426 QString m_pub; 427 QString m_notationName; 428 }; 429 430 class QDomEntityReferencePrivate : public QDomNodePrivate 431 { 432 public: 433 QDomEntityReferencePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name); 434 QDomEntityReferencePrivate(QDomNodePrivate *n, bool deep); 435 436 // Reimplemented from QDomNodePrivate 437 QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()438 QDomNode::NodeType nodeType() const override { return QDomNode::EntityReferenceNode; } 439 virtual void save(QTextStream &s, int, int) const override; 440 }; 441 442 class QDomProcessingInstructionPrivate : public QDomNodePrivate 443 { 444 public: 445 QDomProcessingInstructionPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, 446 const QString &target, const QString &data); 447 QDomProcessingInstructionPrivate(QDomProcessingInstructionPrivate *n, bool deep); 448 449 // Reimplemented from QDomNodePrivate 450 QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()451 QDomNode::NodeType nodeType() const override { return QDomNode::ProcessingInstructionNode; } 452 virtual void save(QTextStream &s, int, int) const override; 453 }; 454 455 class QDomDocumentPrivate : public QDomNodePrivate 456 { 457 public: 458 QDomDocumentPrivate(); 459 QDomDocumentPrivate(const QString &name); 460 QDomDocumentPrivate(QDomDocumentTypePrivate *dt); 461 QDomDocumentPrivate(QDomDocumentPrivate *n, bool deep); 462 ~QDomDocumentPrivate(); 463 464 #if QT_DEPRECATED_SINCE(5, 15) 465 QT_WARNING_PUSH 466 QT_WARNING_DISABLE_DEPRECATED 467 bool setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, 468 int *errorLine, int *errorColumn); 469 bool setContent(QXmlInputSource *source, QXmlReader *reader, QXmlSimpleReader *simpleReader, 470 QString *errorMsg, int *errorLine, int *errorColumn); 471 QT_WARNING_POP 472 #endif 473 bool setContent(QXmlStreamReader *reader, bool namespaceProcessing, QString *errorMsg, 474 int *errorLine, int *errorColumn); 475 476 // Attributes doctype()477 QDomDocumentTypePrivate *doctype() { return type.data(); } implementation()478 QDomImplementationPrivate *implementation() { return impl.data(); } 479 QDomElementPrivate *documentElement(); 480 481 // Factories 482 QDomElementPrivate *createElement(const QString &tagName); 483 QDomElementPrivate *createElementNS(const QString &nsURI, const QString &qName); 484 QDomDocumentFragmentPrivate *createDocumentFragment(); 485 QDomTextPrivate *createTextNode(const QString &data); 486 QDomCommentPrivate *createComment(const QString &data); 487 QDomCDATASectionPrivate *createCDATASection(const QString &data); 488 QDomProcessingInstructionPrivate *createProcessingInstruction(const QString &target, 489 const QString &data); 490 QDomAttrPrivate *createAttribute(const QString &name); 491 QDomAttrPrivate *createAttributeNS(const QString &nsURI, const QString &qName); 492 QDomEntityReferencePrivate *createEntityReference(const QString &name); 493 494 QDomNodePrivate *importNode(QDomNodePrivate *importedNode, bool deep); 495 496 // Reimplemented from QDomNodePrivate 497 QDomNodePrivate *cloneNode(bool deep = true) override; nodeType()498 QDomNode::NodeType nodeType() const override { return QDomNode::DocumentNode; } 499 void clear() override; 500 501 // Variables 502 QExplicitlySharedDataPointer<QDomImplementationPrivate> impl; 503 QExplicitlySharedDataPointer<QDomDocumentTypePrivate> type; 504 505 void saveDocument(QTextStream &stream, const int indent, 506 QDomNode::EncodingPolicy encUsed) const; 507 508 /* \internal 509 Counter for the QDomNodeListPrivate timestamps. 510 511 This is a cache optimization, that might in some cases be effective. The 512 dilemma is that QDomNode::childNodes() returns a list, but the 513 implementation stores the children in a linked list. Hence, in order to 514 get the children out through childNodes(), a list must be populated each 515 time, which is O(N). 516 517 DOM has the requirement of node references being live, see DOM Core 518 Level 3, 1.1.1 The DOM Structure Model, which means that changes to the 519 underlying documents must be reflected in node lists. 520 521 This mechanism, nodeListTime, is a caching optimization that reduces the 522 amount of times the node list is rebuilt, by only doing so when the 523 document actually changes. However, a change to anywhere in any document 524 invalidate all lists, since no dependency tracking is done. 525 526 It functions by that all modifying functions(insertBefore() and so on) 527 increment the count; each QDomNodeListPrivate copies nodeListTime on 528 construction, and compares its own value to nodeListTime in order to 529 determine whether it needs to rebuild. 530 531 This is reentrant. The nodeListTime may overflow, but that's ok since we 532 check for equalness, not whether nodeListTime is smaller than the list's 533 stored timestamp. 534 */ 535 long nodeListTime; 536 }; 537 538 QT_END_NAMESPACE 539 540 #endif // QDOMHELPERS_P_H 541