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 <qshareddata.h>
49
50QT_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
69class QDomImplementationPrivate
70{
71public:
72 inline QDomImplementationPrivate() {}
73
74 QDomImplementationPrivate *clone();
75 QAtomicInt ref;
76 static QDomImplementation::InvalidDataPolicy invalidDataPolicy;
77};
78
79class QDomNodePrivate
80{
81public:
82 QDomNodePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr);
83 QDomNodePrivate(QDomNodePrivate *n, bool deep);
84 virtual ~QDomNodePrivate();
85
86 QString nodeName() const { return name; }
87 QString nodeValue() const { return value; }
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
105 inline QDomNodePrivate *parent() const { return hasParent ? ownerNode : nullptr; }
106 inline void setParent(QDomNodePrivate *p)
107 {
108 ownerNode = p;
109 hasParent = true;
110 }
111
112 void setNoParent()
113 {
114 ownerNode = hasParent ? (QDomNodePrivate *)ownerDocument() : nullptr;
115 hasParent = false;
116 }
117
118 // Dynamic cast
119 bool isAttr() const { return nodeType() == QDomNode::AttributeNode; }
120 bool isCDATASection() const { return nodeType() == QDomNode::CDATASectionNode; }
121 bool isDocumentFragment() const { return nodeType() == QDomNode::DocumentFragmentNode; }
122 bool isDocument() const { return nodeType() == QDomNode::DocumentNode; }
123 bool isDocumentType() const { return nodeType() == QDomNode::DocumentTypeNode; }
124 bool isElement() const { return nodeType() == QDomNode::ElementNode; }
125 bool isEntityReference() const { return nodeType() == QDomNode::EntityReferenceNode; }
126 bool isText() const
127 {
128 const QDomNode::NodeType nt = nodeType();
129 return (nt == QDomNode::TextNode) || (nt == QDomNode::CDATASectionNode);
130 }
131 bool isEntity() const { return nodeType() == QDomNode::EntityNode; }
132 bool isNotation() const { return nodeType() == QDomNode::NotationNode; }
133 bool isProcessingInstruction() const
134 {
135 return nodeType() == QDomNode::ProcessingInstructionNode;
136 }
137 bool isCharacterData() const
138 {
139 const QDomNode::NodeType nt = nodeType();
140 return (nt == QDomNode::CharacterDataNode) || (nt == QDomNode::TextNode)
141 || (nt == QDomNode::CommentNode);
142 }
143 bool isComment() const { return nodeType() == QDomNode::CommentNode; }
144
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
170class QDomNodeListPrivate
171{
172public:
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
196class QDomNamedNodeMapPrivate
197{
198public:
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();
216 bool isReadOnly() { return readonly; }
217 void setReadOnly(bool r) { readonly = r; }
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 */
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
244class QDomDocumentTypePrivate : public QDomNodePrivate
245{
246public:
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
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
272class QDomDocumentFragmentPrivate : public QDomNodePrivate
273{
274public:
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;
280 QDomNode::NodeType nodeType() const override { return QDomNode::DocumentFragmentNode; }
281};
282
283class QDomCharacterDataPrivate : public QDomNodePrivate
284{
285public:
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
297 QDomNode::NodeType nodeType() const override { return QDomNode::CharacterDataNode; }
298 QDomNodePrivate *cloneNode(bool deep = true) override;
299};
300
301class QDomTextPrivate : public QDomCharacterDataPrivate
302{
303public:
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;
311 QDomNode::NodeType nodeType() const override { return QDomNode::TextNode; }
312 virtual void save(QTextStream &s, int, int) const override;
313};
314
315class QDomAttrPrivate : public QDomNodePrivate
316{
317public:
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;
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
335class QDomElementPrivate : public QDomNodePrivate
336{
337public:
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
361 QDomNamedNodeMapPrivate *attributes() { return m_attr; }
362 bool hasAttributes() { return (m_attr->length() > 0); }
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
371class QDomCommentPrivate : public QDomCharacterDataPrivate
372{
373public:
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;
379 QDomNode::NodeType nodeType() const override { return QDomNode::CommentNode; }
380 virtual void save(QTextStream &s, int, int) const override;
381};
382
383class QDomCDATASectionPrivate : public QDomTextPrivate
384{
385public:
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;
391 QDomNode::NodeType nodeType() const override { return QDomNode::CDATASectionNode; }
392 virtual void save(QTextStream &s, int, int) const override;
393};
394
395class QDomNotationPrivate : public QDomNodePrivate
396{
397public:
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;
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
412class QDomEntityPrivate : public QDomNodePrivate
413{
414public:
415 QDomEntityPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name,
416 const QString &pub, const QString &sys, const QString &notation);
417 QDomEntityPrivate(QDomEntityPrivate *n, bool deep);
418
419 // Reimplemented from QDomNodePrivate
420 QDomNodePrivate *cloneNode(bool deep = true) override;
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
430class QDomEntityReferencePrivate : public QDomNodePrivate
431{
432public:
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;
438 QDomNode::NodeType nodeType() const override { return QDomNode::EntityReferenceNode; }
439 virtual void save(QTextStream &s, int, int) const override;
440};
441
442class QDomProcessingInstructionPrivate : public QDomNodePrivate
443{
444public:
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;
451 QDomNode::NodeType nodeType() const override { return QDomNode::ProcessingInstructionNode; }
452 virtual void save(QTextStream &s, int, int) const override;
453};
454
455class QDomDocumentPrivate : public QDomNodePrivate
456{
457public:
458 QDomDocumentPrivate();
459 QDomDocumentPrivate(const QString &name);
460 QDomDocumentPrivate(QDomDocumentTypePrivate *dt);
461 QDomDocumentPrivate(QDomDocumentPrivate *n, bool deep);
462 ~QDomDocumentPrivate();
463
464 bool setContent(QXmlStreamReader *reader, bool namespaceProcessing, QString *errorMsg,
465 int *errorLine, int *errorColumn);
466
467 // Attributes
468 QDomDocumentTypePrivate *doctype() { return type.data(); }
469 QDomImplementationPrivate *implementation() { return impl.data(); }
470 QDomElementPrivate *documentElement();
471
472 // Factories
473 QDomElementPrivate *createElement(const QString &tagName);
474 QDomElementPrivate *createElementNS(const QString &nsURI, const QString &qName);
475 QDomDocumentFragmentPrivate *createDocumentFragment();
476 QDomTextPrivate *createTextNode(const QString &data);
477 QDomCommentPrivate *createComment(const QString &data);
478 QDomCDATASectionPrivate *createCDATASection(const QString &data);
479 QDomProcessingInstructionPrivate *createProcessingInstruction(const QString &target,
480 const QString &data);
481 QDomAttrPrivate *createAttribute(const QString &name);
482 QDomAttrPrivate *createAttributeNS(const QString &nsURI, const QString &qName);
483 QDomEntityReferencePrivate *createEntityReference(const QString &name);
484
485 QDomNodePrivate *importNode(QDomNodePrivate *importedNode, bool deep);
486
487 // Reimplemented from QDomNodePrivate
488 QDomNodePrivate *cloneNode(bool deep = true) override;
489 QDomNode::NodeType nodeType() const override { return QDomNode::DocumentNode; }
490 void clear() override;
491
492 // Variables
493 QExplicitlySharedDataPointer<QDomImplementationPrivate> impl;
494 QExplicitlySharedDataPointer<QDomDocumentTypePrivate> type;
495
496 void saveDocument(QTextStream &stream, const int indent,
497 QDomNode::EncodingPolicy encUsed) const;
498
499 /* \internal
500 Counter for the QDomNodeListPrivate timestamps.
501
502 This is a cache optimization, that might in some cases be effective. The
503 dilemma is that QDomNode::childNodes() returns a list, but the
504 implementation stores the children in a linked list. Hence, in order to
505 get the children out through childNodes(), a list must be populated each
506 time, which is O(N).
507
508 DOM has the requirement of node references being live, see DOM Core
509 Level 3, 1.1.1 The DOM Structure Model, which means that changes to the
510 underlying documents must be reflected in node lists.
511
512 This mechanism, nodeListTime, is a caching optimization that reduces the
513 amount of times the node list is rebuilt, by only doing so when the
514 document actually changes. However, a change to anywhere in any document
515 invalidate all lists, since no dependency tracking is done.
516
517 It functions by that all modifying functions(insertBefore() and so on)
518 increment the count; each QDomNodeListPrivate copies nodeListTime on
519 construction, and compares its own value to nodeListTime in order to
520 determine whether it needs to rebuild.
521
522 This is reentrant. The nodeListTime may overflow, but that's ok since we
523 check for equalness, not whether nodeListTime is smaller than the list's
524 stored timestamp.
525 */
526 long nodeListTime;
527};
528
529QT_END_NAMESPACE
530
531#endif // QDOMHELPERS_P_H
532