/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 ¬ation); |
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 |