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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtbase/src/xml/dom/qdom_p.h