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 void saveSubTree(const QDomNodePrivate *n, QTextStream &s, int depth, int indent) const;
113 virtual void save(QTextStream &, int, int) const {}
114 virtual void afterSave(QTextStream &, int, int) const {}
115
116 void setLocation(int lineNumber, int columnNumber);
117
118 // Variables
119 QAtomicInt ref;
120 QDomNodePrivate *prev;
121 QDomNodePrivate *next;
122 QDomNodePrivate *ownerNode; // either the node's parent or the node's owner document
123 QDomNodePrivate *first;
124 QDomNodePrivate *last;
125
126 QString name; // this is the local name if prefix != null
127 QString value;
128 QString prefix; // set this only for ElementNode and AttributeNode
129 QString namespaceURI; // set this only for ElementNode and AttributeNode
130 bool createdWithDom1Interface : 1;
131 bool hasParent : 1;
132
133 int lineNumber;
134 int columnNumber;
135};
136
137class QDomNodeListPrivate
138{
139public:
140 QDomNodeListPrivate(QDomNodePrivate *);
141 QDomNodeListPrivate(QDomNodePrivate *, const QString &);
142 QDomNodeListPrivate(QDomNodePrivate *, const QString &, const QString &);
143 ~QDomNodeListPrivate();
144
145 bool operator==(const QDomNodeListPrivate &) const noexcept;
146
147 void createList() const;
148 bool maybeCreateList() const;
149 QDomNodePrivate *item(int index);
150 int length() const;
151
152 QAtomicInt ref;
153 /*
154 This list contains the children of this node.
155 */
156 QDomNodePrivate *node_impl;
157 QString tagname;
158 QString nsURI;
159 mutable QList<QDomNodePrivate *> list;
160 mutable long timestamp;
161};
162
163class QDomNamedNodeMapPrivate
164{
165public:
166 QDomNamedNodeMapPrivate(QDomNodePrivate *);
167 ~QDomNamedNodeMapPrivate();
168
169 QDomNodePrivate *namedItem(const QString &name) const;
170 QDomNodePrivate *namedItemNS(const QString &nsURI, const QString &localName) const;
171 QDomNodePrivate *setNamedItem(QDomNodePrivate *arg);
172 QDomNodePrivate *setNamedItemNS(QDomNodePrivate *arg);
173 QDomNodePrivate *removeNamedItem(const QString &name);
174 QDomNodePrivate *item(int index) const;
175 int length() const;
176 bool contains(const QString &name) const;
177 bool containsNS(const QString &nsURI, const QString &localName) const;
178
179 /**
180 * Remove all children from the map.
181 */
182 void clearMap();
183 bool isReadOnly() { return readonly; }
184 void setReadOnly(bool r) { readonly = r; }
185 bool isAppendToParent() { return appendToParent; }
186 /**
187 * If true, then the node will redirect insert/remove calls
188 * to its parent by calling QDomNodePrivate::appendChild or removeChild.
189 * In addition the map won't increase or decrease the reference count
190 * of the nodes it contains.
191 *
192 * By default this value is false and the map will handle reference counting
193 * by itself.
194 */
195 void setAppendToParent(bool b) { appendToParent = b; }
196
197 /**
198 * Creates a copy of the map. It is a deep copy
199 * that means that all children are cloned.
200 */
201 QDomNamedNodeMapPrivate *clone(QDomNodePrivate *parent);
202
203 // Variables
204 QAtomicInt ref;
205 QMultiHash<QString, QDomNodePrivate *> map;
206 QDomNodePrivate *parent;
207 bool readonly;
208 bool appendToParent;
209};
210
211class QDomDocumentTypePrivate : public QDomNodePrivate
212{
213public:
214 QDomDocumentTypePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr);
215 QDomDocumentTypePrivate(QDomDocumentTypePrivate *n, bool deep);
216 ~QDomDocumentTypePrivate();
217 void init();
218
219 // Reimplemented from QDomNodePrivate
220 QDomNodePrivate *cloneNode(bool deep = true) override;
221 QDomNodePrivate *insertBefore(QDomNodePrivate *newChild, QDomNodePrivate *refChild) override;
222 QDomNodePrivate *insertAfter(QDomNodePrivate *newChild, QDomNodePrivate *refChild) override;
223 QDomNodePrivate *replaceChild(QDomNodePrivate *newChild, QDomNodePrivate *oldChild) override;
224 QDomNodePrivate *removeChild(QDomNodePrivate *oldChild) override;
225 QDomNodePrivate *appendChild(QDomNodePrivate *newChild) override;
226
227 QDomNode::NodeType nodeType() const override { return QDomNode::DocumentTypeNode; }
228
229 void save(QTextStream &s, int, int) const override;
230
231 // Variables
232 QDomNamedNodeMapPrivate *entities;
233 QDomNamedNodeMapPrivate *notations;
234 QString publicId;
235 QString systemId;
236 QString internalSubset;
237};
238
239class QDomDocumentFragmentPrivate : public QDomNodePrivate
240{
241public:
242 QDomDocumentFragmentPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr);
243 QDomDocumentFragmentPrivate(QDomNodePrivate *n, bool deep);
244
245 // Reimplemented from QDomNodePrivate
246 virtual QDomNodePrivate *cloneNode(bool deep = true) override;
247 QDomNode::NodeType nodeType() const override { return QDomNode::DocumentFragmentNode; }
248};
249
250class QDomCharacterDataPrivate : public QDomNodePrivate
251{
252public:
253 QDomCharacterDataPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &data);
254 QDomCharacterDataPrivate(QDomCharacterDataPrivate *n, bool deep);
255
256 int dataLength() const;
257 QString substringData(unsigned long offset, unsigned long count) const;
258 void appendData(const QString &arg);
259 void insertData(unsigned long offset, const QString &arg);
260 void deleteData(unsigned long offset, unsigned long count);
261 void replaceData(unsigned long offset, unsigned long count, const QString &arg);
262
263 // Reimplemented from QDomNodePrivate
264 QDomNode::NodeType nodeType() const override { return QDomNode::CharacterDataNode; }
265 QDomNodePrivate *cloneNode(bool deep = true) override;
266};
267
268class QDomTextPrivate : public QDomCharacterDataPrivate
269{
270public:
271 QDomTextPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val);
272 QDomTextPrivate(QDomTextPrivate *n, bool deep);
273
274 QDomTextPrivate *splitText(int offset);
275
276 // Reimplemented from QDomNodePrivate
277 QDomNodePrivate *cloneNode(bool deep = true) override;
278 QDomNode::NodeType nodeType() const override { return QDomNode::TextNode; }
279 virtual void save(QTextStream &s, int, int) const override;
280};
281
282class QDomAttrPrivate : public QDomNodePrivate
283{
284public:
285 QDomAttrPrivate(QDomDocumentPrivate *, QDomNodePrivate *, const QString &name);
286 QDomAttrPrivate(QDomDocumentPrivate *, QDomNodePrivate *, const QString &nsURI,
287 const QString &qName);
288 QDomAttrPrivate(QDomAttrPrivate *n, bool deep);
289
290 bool specified() const;
291
292 // Reimplemented from QDomNodePrivate
293 void setNodeValue(const QString &v) override;
294 QDomNodePrivate *cloneNode(bool deep = true) override;
295 QDomNode::NodeType nodeType() const override { return QDomNode::AttributeNode; }
296 virtual void save(QTextStream &s, int, int) const override;
297
298 // Variables
299 bool m_specified;
300};
301
302class QDomElementPrivate : public QDomNodePrivate
303{
304public:
305 QDomElementPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name);
306 QDomElementPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &nsURI,
307 const QString &qName);
308 QDomElementPrivate(QDomElementPrivate *n, bool deep);
309 ~QDomElementPrivate();
310
311 QString attribute(const QString &name, const QString &defValue) const;
312 QString attributeNS(const QString &nsURI, const QString &localName,
313 const QString &defValue) const;
314 void setAttribute(const QString &name, const QString &value);
315 void setAttributeNS(const QString &nsURI, const QString &qName, const QString &newValue);
316 void removeAttribute(const QString &name);
317 QDomAttrPrivate *attributeNode(const QString &name);
318 QDomAttrPrivate *attributeNodeNS(const QString &nsURI, const QString &localName);
319 QDomAttrPrivate *setAttributeNode(QDomAttrPrivate *newAttr);
320 QDomAttrPrivate *setAttributeNodeNS(QDomAttrPrivate *newAttr);
321 QDomAttrPrivate *removeAttributeNode(QDomAttrPrivate *oldAttr);
322 bool hasAttribute(const QString &name);
323 bool hasAttributeNS(const QString &nsURI, const QString &localName);
324
325 QString text();
326
327 // Reimplemented from QDomNodePrivate
328 QDomNamedNodeMapPrivate *attributes() { return m_attr; }
329 bool hasAttributes() { return (m_attr->length() > 0); }
330 QDomNode::NodeType nodeType() const override { return QDomNode::ElementNode; }
331 QDomNodePrivate *cloneNode(bool deep = true) override;
332 virtual void save(QTextStream &s, int, int) const override;
333 virtual void afterSave(QTextStream &s, int, int) const override;
334
335 // Variables
336 QDomNamedNodeMapPrivate *m_attr;
337};
338
339class QDomCommentPrivate : public QDomCharacterDataPrivate
340{
341public:
342 QDomCommentPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val);
343 QDomCommentPrivate(QDomCommentPrivate *n, bool deep);
344
345 // Reimplemented from QDomNodePrivate
346 QDomNodePrivate *cloneNode(bool deep = true) override;
347 QDomNode::NodeType nodeType() const override { return QDomNode::CommentNode; }
348 virtual void save(QTextStream &s, int, int) const override;
349};
350
351class QDomCDATASectionPrivate : public QDomTextPrivate
352{
353public:
354 QDomCDATASectionPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val);
355 QDomCDATASectionPrivate(QDomCDATASectionPrivate *n, bool deep);
356
357 // Reimplemented from QDomNodePrivate
358 QDomNodePrivate *cloneNode(bool deep = true) override;
359 QDomNode::NodeType nodeType() const override { return QDomNode::CDATASectionNode; }
360 virtual void save(QTextStream &s, int, int) const override;
361};
362
363class QDomNotationPrivate : public QDomNodePrivate
364{
365public:
366 QDomNotationPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name,
367 const QString &pub, const QString &sys);
368 QDomNotationPrivate(QDomNotationPrivate *n, bool deep);
369
370 // Reimplemented from QDomNodePrivate
371 QDomNodePrivate *cloneNode(bool deep = true) override;
372 QDomNode::NodeType nodeType() const override { return QDomNode::NotationNode; }
373 virtual void save(QTextStream &s, int, int) const override;
374
375 // Variables
376 QString m_sys;
377 QString m_pub;
378};
379
380class QDomEntityPrivate : public QDomNodePrivate
381{
382public:
383 QDomEntityPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name,
384 const QString &pub, const QString &sys, const QString &notation);
385 QDomEntityPrivate(QDomEntityPrivate *n, bool deep);
386
387 // Reimplemented from QDomNodePrivate
388 QDomNodePrivate *cloneNode(bool deep = true) override;
389 QDomNode::NodeType nodeType() const override { return QDomNode::EntityNode; }
390 virtual void save(QTextStream &s, int, int) const override;
391
392 // Variables
393 QString m_sys;
394 QString m_pub;
395 QString m_notationName;
396};
397
398class QDomEntityReferencePrivate : public QDomNodePrivate
399{
400public:
401 QDomEntityReferencePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name);
402 QDomEntityReferencePrivate(QDomNodePrivate *n, bool deep);
403
404 // Reimplemented from QDomNodePrivate
405 QDomNodePrivate *cloneNode(bool deep = true) override;
406 QDomNode::NodeType nodeType() const override { return QDomNode::EntityReferenceNode; }
407 virtual void save(QTextStream &s, int, int) const override;
408};
409
410class QDomProcessingInstructionPrivate : public QDomNodePrivate
411{
412public:
413 QDomProcessingInstructionPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent,
414 const QString &target, const QString &data);
415 QDomProcessingInstructionPrivate(QDomProcessingInstructionPrivate *n, bool deep);
416
417 // Reimplemented from QDomNodePrivate
418 QDomNodePrivate *cloneNode(bool deep = true) override;
419 QDomNode::NodeType nodeType() const override { return QDomNode::ProcessingInstructionNode; }
420 virtual void save(QTextStream &s, int, int) const override;
421};
422
423class QDomDocumentPrivate : public QDomNodePrivate
424{
425public:
426 QDomDocumentPrivate();
427 QDomDocumentPrivate(const QString &name);
428 QDomDocumentPrivate(QDomDocumentTypePrivate *dt);
429 QDomDocumentPrivate(QDomDocumentPrivate *n, bool deep);
430 ~QDomDocumentPrivate();
431
432 QDomDocument::ParseResult setContent(QXmlStreamReader *reader,
433 QDomDocument::ParseOptions options);
434
435 // Attributes
436 QDomDocumentTypePrivate *doctype() { return type.data(); }
437 QDomImplementationPrivate *implementation() { return impl.data(); }
438 QDomElementPrivate *documentElement();
439
440 // Factories
441 QDomElementPrivate *createElement(const QString &tagName);
442 QDomElementPrivate *createElementNS(const QString &nsURI, const QString &qName);
443 QDomDocumentFragmentPrivate *createDocumentFragment();
444 QDomTextPrivate *createTextNode(const QString &data);
445 QDomCommentPrivate *createComment(const QString &data);
446 QDomCDATASectionPrivate *createCDATASection(const QString &data);
447 QDomProcessingInstructionPrivate *createProcessingInstruction(const QString &target,
448 const QString &data);
449 QDomAttrPrivate *createAttribute(const QString &name);
450 QDomAttrPrivate *createAttributeNS(const QString &nsURI, const QString &qName);
451 QDomEntityReferencePrivate *createEntityReference(const QString &name);
452
453 QDomNodePrivate *importNode(QDomNodePrivate *importedNode, bool deep);
454
455 // Reimplemented from QDomNodePrivate
456 QDomNodePrivate *cloneNode(bool deep = true) override;
457 QDomNode::NodeType nodeType() const override { return QDomNode::DocumentNode; }
458 void clear() override;
459
460 // Variables
461 QExplicitlySharedDataPointer<QDomImplementationPrivate> impl;
462 QExplicitlySharedDataPointer<QDomDocumentTypePrivate> type;
463
464 void saveDocument(QTextStream &stream, const int indent,
465 QDomNode::EncodingPolicy encUsed) const;
466
467 /* \internal
468 Counter for the QDomNodeListPrivate timestamps.
469
470 This is a cache optimization, that might in some cases be effective. The
471 dilemma is that QDomNode::childNodes() returns a list, but the
472 implementation stores the children in a linked list. Hence, in order to
473 get the children out through childNodes(), a list must be populated each
474 time, which is O(N).
475
476 DOM has the requirement of node references being live, see DOM Core
477 Level 3, 1.1.1 The DOM Structure Model, which means that changes to the
478 underlying documents must be reflected in node lists.
479
480 This mechanism, nodeListTime, is a caching optimization that reduces the
481 amount of times the node list is rebuilt, by only doing so when the
482 document actually changes. However, a change to anywhere in any document
483 invalidate all lists, since no dependency tracking is done.
484
485 It functions by that all modifying functions(insertBefore() and so on)
486 increment the count; each QDomNodeListPrivate copies nodeListTime on
487 construction, and compares its own value to nodeListTime in order to
488 determine whether it needs to rebuild.
489
490 This is reentrant. The nodeListTime may overflow, but that's ok since we
491 check for equalness, not whether nodeListTime is smaller than the list's
492 stored timestamp.
493 */
494 long nodeListTime;
495};
496
497QT_END_NAMESPACE
498
499#endif // QDOMHELPERS_P_H
500

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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