dcfb388c152be900fa693d9fbaddcce58cba2f83
[profile/ivi/qtxmlpatterns.git] / src / xmlpatterns / api / qabstractxmlnodemodel.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QABSTRACTXMLNODEMODEL_H
43 #define QABSTRACTXMLNODEMODEL_H
44
45 #include <QtXmlPatterns/QXmlName>
46 #include <QtCore/QSharedData>
47 #include <QtCore/QScopedPointer>
48
49 QT_BEGIN_HEADER
50 QT_BEGIN_NAMESPACE
51
52
53 /* This file contains the classes QXmlNodeModelIndex, QAbstractXmlNodeModel,
54  * QXmlItem and QPatternist::NodeIndexStorage. */
55
56 class QAbstractXmlNodeModel;
57 class QAbstractXmlNodeModelPrivate;
58 class QAbstractXmlReceiver;
59 class QSourceLocation;
60 class QUrl;
61 class QXmlName;
62 class QXmlNodeModelIndex;
63 template<typename T> class QAbstractXmlForwardIterator;
64 template<typename T> class QVector;
65
66 /* The members in the namespace QPatternist are internal, not part of the public API, and
67  * unsupported. Using them leads to undefined behavior. */
68 namespace QPatternist
69 {
70     class DynamicContext;
71     class Item;
72     class ItemType;
73     class XsdValidatedXmlNodeModel;
74     template<typename TResult, typename TSource, typename TMapper, typename Context> class ItemMappingIterator;
75     template<typename TResult, typename TSource, typename TMapper> class SequenceMappingIterator;
76     typedef QExplicitlySharedDataPointer<ItemType> ItemTypePtr;
77     typedef QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<Item> > ItemIteratorPtr;
78     typedef QVector<QXmlName> QXmlNameVector;
79
80     class NodeIndexStorage
81     {
82     public:
83         typedef qint64 Data;
84
85         /*!
86           \note Changing merely the order of these two members, ptr and data,
87                 is a binary incompatible change on Mac Power PC.
88          */
89         union
90         {
91             void *ptr; // Do not use ptr directy, use pointer() instead.
92             Data data;
93         };
94         void *pointer() const
95         {
96             /* Constructing to qptrdiff means we avoid the warning "cast to pointer
97              * from integer of different size."
98              */
99             return (void *)qptrdiff(data);
100         }
101
102         Data additionalData;
103         const QAbstractXmlNodeModel *model;
104
105         /* Implementation is in qabstractxmlnodemodel.cpp. */
106         inline bool operator!=(const NodeIndexStorage &other) const;
107
108         void reset()
109         {
110             data = 0;
111             additionalData = 0;
112             model = 0;
113         }
114     };
115 }
116
117 class Q_XMLPATTERNS_EXPORT QXmlNodeModelIndex
118 {
119     enum Constants
120     {
121         ForwardAxis         = 8192,
122         ReverseAxis         = 16384
123     };
124
125 public:
126     inline QXmlNodeModelIndex()
127     {
128         reset();
129     }
130
131     inline QXmlNodeModelIndex(const QXmlNodeModelIndex &other) : m_storage(other.m_storage)
132     {
133     }
134
135     bool operator==(const QXmlNodeModelIndex &other) const;
136     bool operator!=(const QXmlNodeModelIndex &other) const;
137
138     typedef QAbstractXmlForwardIterator<QXmlNodeModelIndex> Iterator;
139     typedef QList<QXmlNodeModelIndex> List;
140
141     enum NodeKind
142     {
143         Attribute               = 1,
144         Comment                 = 2,
145         Document                = 4,
146         Element                 = 8,
147         Namespace               = 16,
148         ProcessingInstruction   = 32,
149         Text                    = 64
150     };
151
152     enum DocumentOrder
153     {
154         Precedes = -1,
155         Is       = 0,
156         Follows  = 1
157     };
158
159     enum Axis
160     {
161         AxisChild               = 1 | ForwardAxis,
162         AxisDescendant          = 2 | ForwardAxis,
163         AxisAttribute           = 4 | ForwardAxis,
164         AxisSelf                = 8 | ForwardAxis,
165         AxisDescendantOrSelf    = 16 | ForwardAxis,
166         AxisFollowingSibling    = 32 | ForwardAxis,
167         AxisNamespace           = 64 | ForwardAxis,
168         AxisFollowing           = 128 | ReverseAxis,
169         AxisParent              = 256 | ReverseAxis,
170         AxisAncestor            = 512 | ReverseAxis,
171         AxisPrecedingSibling    = 1024 | ReverseAxis,
172         AxisPreceding           = 2048 | ReverseAxis,
173         AxisAncestorOrSelf      = 4096 | ReverseAxis,
174         /* Note that we cannot clash with the values of ForwardAxis and
175          * ReverseAxis. */
176         AxisChildOrTop          = 32768 | ForwardAxis,
177         AxisAttributeOrTop      = 65536 | ForwardAxis
178     };
179
180     inline qint64 data() const
181     {
182         return m_storage.data;
183     }
184
185     inline void *internalPointer() const
186     {
187         return m_storage.pointer();
188     }
189
190     inline const QAbstractXmlNodeModel *model() const
191     {
192         return m_storage.model;
193     }
194
195     inline qint64 additionalData() const
196     {
197         return m_storage.additionalData;
198     }
199
200     inline bool isNull() const
201     {
202         return !m_storage.model;
203     }
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
229 private:
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
263 Q_XMLPATTERNS_EXPORT uint qHash(const QXmlNodeModelIndex &index);
264
265 inline bool qIsForwardIteratorEnd(const QXmlNodeModelIndex &item)
266 {
267     return item.isNull();
268 }
269
270 class Q_XMLPATTERNS_EXPORT QAbstractXmlNodeModel : public QSharedData
271 {
272 public:
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
327 protected:
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(data, this);
337     }
338
339     inline QXmlNodeModelIndex createIndex(void * pointer,
340                                           qint64 additionalData = 0) const
341     {
342         return QXmlNodeModelIndex::create(qptrdiff(pointer), this, additionalData);
343     }
344
345     inline QXmlNodeModelIndex createIndex(qint64 data,
346                                           qint64 additionalData) const
347     {
348         return QXmlNodeModelIndex::create(data, this, additionalData);
349     }
350
351     QScopedPointer<QAbstractXmlNodeModelPrivate> d_ptr;
352 private:
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
364 Q_DECLARE_TYPEINFO(QXmlNodeModelIndex, Q_MOVABLE_TYPE);
365
366 template<typename T> class QAbstractXmlForwardIterator;
367 class QVariant;
368 class QXmlItemPrivate;
369
370 namespace QPatternist
371 {
372     class AtomicValue;
373     class VariableLoader;
374     class IteratorBridge;
375     class ToQXmlItemMapper;
376     class ToItemMapper;
377 }
378
379 class Q_XMLPATTERNS_EXPORT QXmlItem
380 {
381 public:
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
398 private:
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
420 inline bool qIsForwardIteratorEnd(const QXmlItem &item)
421 {
422     return item.isNull();
423 }
424
425 Q_DECLARE_TYPEINFO(QXmlItem, Q_MOVABLE_TYPE);
426
427 QT_END_NAMESPACE
428
429 Q_DECLARE_METATYPE(QXmlItem) /* This macro must appear after QT_END_NAMESPACE. */
430
431 QT_END_HEADER
432
433 #endif