Coverage Report

Created: 2026-08-25 06:40

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