1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtXmlPatterns 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
40#ifndef QABSTRACTXMLNODEMODEL_H
41#define QABSTRACTXMLNODEMODEL_H
42
43#include <QtXmlPatterns/QXmlName>
44#include <QtCore/QSharedData>
45#include <QtCore/QScopedPointer>
46
47QT_BEGIN_NAMESPACE
48
49
50/* This file contains the classes QXmlNodeModelIndex, QAbstractXmlNodeModel,
51 * QXmlItem and QPatternist::NodeIndexStorage. */
52
53class QAbstractXmlNodeModel;
54class QAbstractXmlNodeModelPrivate;
55class QAbstractXmlReceiver;
56class QSourceLocation;
57class QUrl;
58class QXmlName;
59class QXmlNodeModelIndex;
60template<typename T> class QAbstractXmlForwardIterator;
61template<typename T> class QVector;
62
63/* The members in the namespace QPatternist are internal, not part of the public API, and
64 * unsupported. Using them leads to undefined behavior. */
65namespace QPatternist
66{
67 class DynamicContext;
68 class Item;
69 class ItemType;
70 class XsdValidatedXmlNodeModel;
71 template<typename TResult, typename TSource, typename TMapper, typename Context> class ItemMappingIterator;
72 template<typename TResult, typename TSource, typename TMapper> class SequenceMappingIterator;
73 typedef QExplicitlySharedDataPointer<ItemType> ItemTypePtr;
74 typedef QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<Item> > ItemIteratorPtr;
75 typedef QVector<QXmlName> QXmlNameVector;
76
77 class NodeIndexStorage
78 {
79 public:
80 typedef qint64 Data;
81
82 /*!
83 \note Changing merely the order of these two members, ptr and data,
84 is a binary incompatible change on Mac Power PC.
85 */
86 union
87 {
88 void *ptr; // Do not use ptr directy, use pointer() instead.
89 Data data;
90 };
91 void *pointer() const
92 {
93 // Constructing via qptrdiff avoids warnings:
94 return reinterpret_cast<void*>(qptrdiff(data));
95 }
96
97 Data additionalData;
98 const QAbstractXmlNodeModel *model;
99
100 /* Implementation is in qabstractxmlnodemodel.cpp. */
101 inline bool operator!=(const NodeIndexStorage &other) const;
102
103 void reset()
104 {
105 data = 0;
106 additionalData = 0;
107 model = nullptr;
108 }
109 };
110}
111
112class Q_XMLPATTERNS_EXPORT QXmlNodeModelIndex
113{
114 enum Constants
115 {
116 ForwardAxis = 8192,
117 ReverseAxis = 16384
118 };
119
120public:
121 inline QXmlNodeModelIndex()
122 {
123 reset();
124 }
125
126 inline QXmlNodeModelIndex(const QXmlNodeModelIndex &other) : m_storage(other.m_storage)
127 {
128 }
129
130 QXmlNodeModelIndex &operator=(const QXmlNodeModelIndex &) = default;
131
132 bool operator==(const QXmlNodeModelIndex &other) const;
133 bool operator!=(const QXmlNodeModelIndex &other) const;
134
135 typedef QAbstractXmlForwardIterator<QXmlNodeModelIndex> Iterator;
136 typedef QList<QXmlNodeModelIndex> List;
137
138 enum NodeKind
139 {
140 Attribute = 1,
141 Comment = 2,
142 Document = 4,
143 Element = 8,
144 Namespace = 16,
145 ProcessingInstruction = 32,
146 Text = 64
147 };
148
149 enum DocumentOrder
150 {
151 Precedes = -1,
152 Is = 0,
153 Follows = 1
154 };
155
156 enum Axis
157 {
158 AxisChild = 1 | ForwardAxis,
159 AxisDescendant = 2 | ForwardAxis,
160 AxisAttribute = 4 | ForwardAxis,
161 AxisSelf = 8 | ForwardAxis,
162 AxisDescendantOrSelf = 16 | ForwardAxis,
163 AxisFollowingSibling = 32 | ForwardAxis,
164 AxisNamespace = 64 | ForwardAxis,
165 AxisFollowing = 128 | ReverseAxis,
166 AxisParent = 256 | ReverseAxis,
167 AxisAncestor = 512 | ReverseAxis,
168 AxisPrecedingSibling = 1024 | ReverseAxis,
169 AxisPreceding = 2048 | ReverseAxis,
170 AxisAncestorOrSelf = 4096 | ReverseAxis,
171 /* Note that we cannot clash with the values of ForwardAxis and
172 * ReverseAxis. */
173 AxisChildOrTop = 32768 | ForwardAxis,
174 AxisAttributeOrTop = 65536 | ForwardAxis
175 };
176
177 inline qint64 data() const
178 {
179 return m_storage.data;
180 }
181
182 inline void *internalPointer() const
183 {
184 return m_storage.pointer();
185 }
186
187 inline const QAbstractXmlNodeModel *model() const
188 {
189 return m_storage.model;
190 }
191
192QT_WARNING_PUSH
193QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
194 inline qint64 additionalData() const
195 {
196 return m_storage.additionalData;
197 }
198
199 inline bool isNull() const
200 {
201 return !m_storage.model;
202 }
203QT_WARNING_POP
204
205 /* The members below are internal, not part of the public API, and
206 * unsupported. Using them leads to undefined behavior. */
207
208 inline QXmlName name() const;
209 inline QXmlNodeModelIndex root() const;
210 inline QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > iterate(const Axis axis) const;
211 inline QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > sequencedTypedValue() const;
212 inline QUrl documentUri() const;
213 inline QUrl baseUri() const;
214 inline NodeKind kind() const;
215 inline bool isDeepEqual(const QXmlNodeModelIndex &other) const;
216 inline DocumentOrder compareOrder(const QXmlNodeModelIndex &other) const;
217 inline void sendNamespaces(QAbstractXmlReceiver *const receiver) const;
218 inline QVector<QXmlName> namespaceBindings() const;
219 inline QXmlName::NamespaceCode namespaceForPrefix(const QXmlName::PrefixCode prefix) const;
220 inline QString stringValue() const;
221 inline QPatternist::ItemTypePtr type() const;
222 inline bool is(const QXmlNodeModelIndex &other) const;
223
224 inline void reset()
225 {
226 m_storage.reset();
227 }
228
229private:
230 static inline QXmlNodeModelIndex create(const qint64 d,
231 const QAbstractXmlNodeModel *const nm)
232 {
233 QXmlNodeModelIndex n;
234 n.m_storage.data = d;
235 n.m_storage.model = nm;
236 n.m_storage.additionalData = 0;
237 return n;
238 }
239
240 static inline QXmlNodeModelIndex create(const qint64 data,
241 const QAbstractXmlNodeModel *const nm,
242 const qint64 addData)
243 {
244 QXmlNodeModelIndex n;
245 n.m_storage.data = data;
246 n.m_storage.model = nm;
247 n.m_storage.additionalData = addData;
248 return n;
249 }
250
251 inline QXmlNodeModelIndex(const QPatternist::NodeIndexStorage &storage) : m_storage(storage)
252 {
253 }
254
255 friend class QAbstractXmlNodeModel;
256 friend class QPatternist::Item;
257 friend class QXmlItem;
258 inline operator int() const; // Disable
259
260 QPatternist::NodeIndexStorage m_storage;
261};
262
263Q_XMLPATTERNS_EXPORT uint qHash(const QXmlNodeModelIndex &index);
264
265inline bool qIsForwardIteratorEnd(const QXmlNodeModelIndex &item)
266{
267 return item.isNull();
268}
269
270class Q_XMLPATTERNS_EXPORT QAbstractXmlNodeModel : public QSharedData
271{
272public:
273 enum SimpleAxis
274 {
275 Parent,
276 FirstChild,
277 PreviousSibling,
278 NextSibling
279 };
280
281 typedef QExplicitlySharedDataPointer<QAbstractXmlNodeModel> Ptr;
282 typedef QList<Ptr> List;
283
284 QAbstractXmlNodeModel();
285 virtual ~QAbstractXmlNodeModel();
286
287 virtual QUrl baseUri(const QXmlNodeModelIndex &ni) const = 0;
288 virtual QUrl documentUri(const QXmlNodeModelIndex &ni) const = 0;
289 virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const = 0;
290 virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &ni1,
291 const QXmlNodeModelIndex &ni2) const = 0;
292 virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &n) const = 0;
293 virtual QXmlName name(const QXmlNodeModelIndex &ni) const = 0;
294 virtual QString stringValue(const QXmlNodeModelIndex &n) const = 0;
295 virtual QVariant typedValue(const QXmlNodeModelIndex &n) const = 0;
296
297 /* The members below are internal, not part of the public API, and
298 * unsupported. Using them leads to undefined behavior. */
299 virtual QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > iterate(const QXmlNodeModelIndex &ni, QXmlNodeModelIndex::Axis axis) const;
300 virtual QPatternist::ItemIteratorPtr sequencedTypedValue(const QXmlNodeModelIndex &ni) const;
301 virtual QPatternist::ItemTypePtr type(const QXmlNodeModelIndex &ni) const;
302 virtual QXmlName::NamespaceCode namespaceForPrefix(const QXmlNodeModelIndex &ni,
303 const QXmlName::PrefixCode prefix) const;
304 virtual bool isDeepEqual(const QXmlNodeModelIndex &ni1,
305 const QXmlNodeModelIndex &ni2) const;
306 virtual void sendNamespaces(const QXmlNodeModelIndex &n,
307 QAbstractXmlReceiver *const receiver) const;
308 virtual QVector<QXmlName> namespaceBindings(const QXmlNodeModelIndex &n) const = 0;
309
310
311 virtual QXmlNodeModelIndex elementById(const QXmlName &NCName) const = 0;
312 virtual QVector<QXmlNodeModelIndex> nodesByIdref(const QXmlName &NCName) const = 0;
313
314 enum NodeCopySetting
315 {
316 InheritNamespaces = 0x1,
317 PreserveNamespaces = 0x2
318 };
319
320 typedef QFlags<NodeCopySetting> NodeCopySettings;
321 virtual void copyNodeTo(const QXmlNodeModelIndex &node,
322 QAbstractXmlReceiver *const receiver,
323 const NodeCopySettings &) const;
324
325 QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const;
326
327protected:
328
329 virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const = 0;
330 virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex &element) const = 0;
331
332 QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d);
333
334 inline QXmlNodeModelIndex createIndex(qint64 data) const
335 {
336 return QXmlNodeModelIndex::create(d: data, nm: this);
337 }
338
339 inline QXmlNodeModelIndex createIndex(void * pointer,
340 qint64 additionalData = 0) const
341 {
342 return QXmlNodeModelIndex::create(data: qptrdiff(pointer), nm: this, addData: additionalData);
343 }
344
345 inline QXmlNodeModelIndex createIndex(qint64 data,
346 qint64 additionalData) const
347 {
348 return QXmlNodeModelIndex::create(data, nm: this, addData: additionalData);
349 }
350
351 QScopedPointer<QAbstractXmlNodeModelPrivate> d_ptr;
352private:
353 friend class QPatternist::ItemMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *, QExplicitlySharedDataPointer<QPatternist::DynamicContext> >;
354 friend class QPatternist::SequenceMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *>;
355 friend class QPatternist::XsdValidatedXmlNodeModel;
356
357 inline QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > mapToSequence(const QXmlNodeModelIndex &ni,
358 const QExplicitlySharedDataPointer<QPatternist::DynamicContext> &) const;
359
360 static inline bool isIgnorableInDeepEqual(const QXmlNodeModelIndex &n);
361 Q_DISABLE_COPY(QAbstractXmlNodeModel)
362};
363
364Q_DECLARE_TYPEINFO(QXmlNodeModelIndex, Q_MOVABLE_TYPE);
365
366template<typename T> class QAbstractXmlForwardIterator;
367class QVariant;
368class QXmlItemPrivate;
369
370namespace QPatternist
371{
372 class AtomicValue;
373 class VariableLoader;
374 class IteratorBridge;
375 class ToQXmlItemMapper;
376 class ToItemMapper;
377}
378
379class Q_XMLPATTERNS_EXPORT QXmlItem
380{
381public:
382 typedef QAbstractXmlForwardIterator<QXmlItem> Iterator;
383
384 QXmlItem();
385 QXmlItem(const QXmlItem &other);
386 QXmlItem(const QXmlNodeModelIndex &node);
387 QXmlItem(const QVariant &atomicValue);
388 ~QXmlItem();
389 QXmlItem &operator=(const QXmlItem &other);
390
391 bool isNull() const;
392 bool isNode() const;
393 bool isAtomicValue() const;
394
395 QVariant toAtomicValue() const;
396 QXmlNodeModelIndex toNodeModelIndex() const;
397
398private:
399 friend class QPatternist::IteratorBridge;
400 friend class QPatternist::VariableLoader;
401 friend class QPatternist::ToQXmlItemMapper;
402 friend class QPatternist::ToItemMapper;
403 friend class QPatternist::Item;
404
405 inline bool internalIsAtomicValue() const;
406
407 inline QXmlItem(const QPatternist::Item &i);
408
409 union
410 {
411 QPatternist::NodeIndexStorage m_node;
412
413 /* These two sits at the position of NodeIndexStorage::data.
414 * NodeIndexStorage::{additionalData,model} are free. */
415 const QPatternist::AtomicValue *m_atomicValue;
416 QXmlItemPrivate * m_ptr; /* Not currently used. */
417 };
418};
419
420inline bool qIsForwardIteratorEnd(const QXmlItem &item)
421{
422 return item.isNull();
423}
424
425Q_DECLARE_TYPEINFO(QXmlItem, Q_MOVABLE_TYPE);
426
427QT_END_NAMESPACE
428
429Q_DECLARE_METATYPE(QXmlItem) /* This macro must appear after QT_END_NAMESPACE. */
430
431#endif
432

source code of qtxmlpatterns/src/xmlpatterns/api/qabstractxmlnodemodel.h