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

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