diff options
author | Alexis Menard <alexis.menard@nokia.com> | 2009-04-17 14:06:06 (GMT) |
---|---|---|
committer | Alexis Menard <alexis.menard@nokia.com> | 2009-04-17 14:06:06 (GMT) |
commit | f15b8a83e2e51955776a3f07cb85ebfc342dd8ef (patch) | |
tree | c5dc684986051654898db11ce73e03b9fec8db99 /src/xmlpatterns/data/qitem_p.h | |
download | Qt-f15b8a83e2e51955776a3f07cb85ebfc342dd8ef.zip Qt-f15b8a83e2e51955776a3f07cb85ebfc342dd8ef.tar.gz Qt-f15b8a83e2e51955776a3f07cb85ebfc342dd8ef.tar.bz2 |
Initial import of statemachine branch from the old kinetic repository
Diffstat (limited to 'src/xmlpatterns/data/qitem_p.h')
-rw-r--r-- | src/xmlpatterns/data/qitem_p.h | 542 |
1 files changed, 542 insertions, 0 deletions
diff --git a/src/xmlpatterns/data/qitem_p.h b/src/xmlpatterns/data/qitem_p.h new file mode 100644 index 0000000..987a1c2 --- /dev/null +++ b/src/xmlpatterns/data/qitem_p.h @@ -0,0 +1,542 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Item_H +#define Patternist_Item_H + +#include <QtXmlPatterns/private/qcppcastinghelper_p.h> +#include <QtXmlPatterns/private/qitemtype_p.h> +#include <QtXmlPatterns/private/qsingletoniterator_p.h> +#include <QtXmlPatterns/QAbstractXmlNodeModel> + +#include <QUrl> +#include <QVariant> + +/** + * @file + * @short Due to strong interdependencies, this file contains the definitions for + * the classes Item, QXmlNodeModelIndex, QAbstractXmlNodeModel and AtomicValue. The implementations are + * in their respective source files. + */ + +/** + * @class QSharedData + * @short Qt's base class for reference counting. + * @author Trolltech + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +template<typename T> class QList; +template<typename T> class QVector; +template<typename T> class QAbstractXmlForwardIterator; + +class QSourceLocation; +class QAbstractXmlReceiver; + +namespace QPatternist +{ + class DynamicContext; + class Item; + class ItemType; + class QObjectNodeModel; + template<typename T> class EmptyIterator; + template<typename T, typename ListType> class ListIterator; + + /** + * @short Base class for all classes representing atomic values. + * + * Instantiating AtomicValues sub classes from a value of somekind, + * for a certain type is done in three different ways: + * + * - The static factory fromLexical which available in most classes. This + * function attempts to create a value from a QString that is considered + * a lexical representation of the value. Thus, this function performs validation, takes + * care of whitespace facets, and everything else related to instantiating a value from + * a lexical representation. + * - The static factory function fromValue. This function exists for + * values where a C++ type exists which corresponds to the type's value space. + * - By using instances available in CommonValues. This is the preferred method + * since it uses existing singleton instances and thus saves memory. CommonValues + * should be used whenever possible, it can be thought as a collection of constant values. + * + * For types that does not distinguish the value space and lexical space, such as <tt>xs:string</tt>, + * only the fromValue() function exist, and fromLexical() is omitted. + * + * @ingroup Patternist_xdm + * @author Frans Englich <fenglich@trolltech.com> + */ + class AtomicValue : public QSharedData + , public CppCastingHelper<AtomicValue> + { + public: + virtual ~AtomicValue(); + + /** + * A smart pointer wrapping AtomicValue instances. + */ + typedef QExplicitlySharedDataPointer<AtomicValue> Ptr; + + /** + * Determines whether this atomic value has an error. This is used + * for implementing casting. + * + * @returns always @c false + */ + virtual bool hasError() const; + + /** + * Always fails by issuing the type error ReportContext::FORG0006. Sub-classes + * whose represented type do allow EBV to be extracted from, must thus + * re-implement this function. + */ + virtual bool evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &context) const; + + virtual QString stringValue() const = 0; + virtual ItemType::Ptr type() const = 0; + + /** + * Converts @p value to a QVariant. + */ + static QVariant toQt(const AtomicValue *const value); + + static inline QVariant toQt(const AtomicValue::Ptr &value) + { + return toQt(value.data()); + } + + static Item toXDM(const QVariant &value); + + static ItemType::Ptr qtToXDMType(const QXmlItem &item); + protected: + inline AtomicValue() + { + } + }; + + /** + * @short Represents an item in the XPath 2.0 Data Model. + * + * There exists two types of items: nodes and atomic values. + * + * The XQuery 1.0 and XPath 2.0 Data Model and XML Path Language (XPath) 2.0 specification + * makes a very strong distinction between a sequence of items and an atomized sequence. + * + * @ingroup Patternist_xdm + * @author Frans Englich <fenglich@trolltech.com> + */ + class Item + { + friend class QT_PREPEND_NAMESPACE(QXmlItem); + + public: + /** + * A smart pointer wrapping an Item instance. + */ + typedef QAbstractXmlForwardIterator<Item> Iterator; + + /** + * A list of Item instances, each wrapped in a smart pointer. + */ + typedef QList<Item> List; + + /** + * A vector of Item instances, each wrapped in a smart pointer. + */ + typedef QVector<Item> Vector; + + typedef QPatternist::SingletonIterator<Item> SingletonIterator; + typedef QPatternist::EmptyIterator<Item> EmptyIterator; + + /** + * Default constructor. + */ + inline Item() + { + /* Note that this function should be equal to reset(). */ + + /* This is the area which atomicValue uses. Becauase we want as() + * to return null on null-constructed objects, we initialize it. */ + node.data = 0; + + /* This signals that we're not an atomic value. */ + node.model = 0; + } + + inline Item(const QXmlNodeModelIndex &n) : node(n.m_storage) + { + } + + inline Item(const Item &other) : node(other.node) + { + Q_ASSERT_X(sizeof(QXmlNodeModelIndex) >= sizeof(AtomicValue), Q_FUNC_INFO, + "Since we're only copying the node member, it must be the largest."); + if(isAtomicValue()) + atomicValue->ref.ref(); + } + + inline Item(const AtomicValue::Ptr &a) + { + if(a) + { + atomicValue = a.data(); + atomicValue->ref.ref(); + + /* Signal that we're housing an atomic value. */ + node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0); + } + else + node.model = 0; /* Like the default constructor. */ + } + + inline Item(const AtomicValue *const a) + { + /* Note, the implementation is a copy of the constructor above. */ + + if(a) + { + atomicValue = a; + atomicValue->ref.ref(); + + /* Signal that we're housing an atomic value. */ + node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0); + } + else + node.model = 0; /* Like the default constructor. */ + } + + inline ~Item() + { + if(isAtomicValue() && !atomicValue->ref.deref()) + delete atomicValue; + } + + inline Item &operator=(const Item &other) + { + Q_ASSERT_X(sizeof(QXmlNodeModelIndex) >= sizeof(AtomicValue *), Q_FUNC_INFO, + "If this doesn't hold, we won't copy all data."); + + if(other.isAtomicValue()) + other.atomicValue->ref.ref(); + + if(isAtomicValue()) + { + if(!atomicValue->ref.deref()) + delete atomicValue; + } + + node = other.node; + + return *this; + } + + template<typename TCastTarget> + inline TCastTarget *as() const + { +#if defined(Patternist_DEBUG) && !defined(Q_CC_XLC) +/* At least on aix-xlc-64, the compiler cries when it sees dynamic_cast. */ + Q_ASSERT_X(atomicValue == 0 || dynamic_cast<const TCastTarget *>(atomicValue), + Q_FUNC_INFO, + "The cast is invalid. This class does not inherit the cast target."); +#endif + return const_cast<TCastTarget *>(static_cast<const TCastTarget *>(atomicValue)); + } + + /** + * @short Returns the string value of this Item. + * + * In the case of a node, it is the node value corresponding to + * the particular node type. For atomic values, it is equivalent + * to the value cast as <tt>xs:string</tt>. + * + * Conceptually, this functions corresponds to the <tt>dm:string-value</tt> accessor. + * + * @see <a href="http://www.w3.org/TR/xpath-datamodel/#dm-string-value">XQuery 1.0 and + * XPath 2.0 Data Model, 5.13 string-value Accessor</a> + * @returns the string value. + */ + inline QString stringValue() const + { + if(isAtomicValue()) + return atomicValue->stringValue(); + else + return asNode().stringValue(); + } + + /** + * @short Returns the typed value of this item. + * + * Conceptually, this functions corresponds to the <tt>dm:typed-value</tt> accessor. Here are + * examples of what the typed value of an Item is: + * + * - The typed value of an atomic value is always the atomic value itself. + * - A comment node has always a typed value of type @c xs:string + * - For attribute and element nodes, the typed value can be arbitrary. For example, an + * element can have a sequence of @c xs:dateTime instances. + * + * @returns the typed value of this item + * @see <a href="http://www.w3.org/TR/xpath-datamodel/#dm-typed-value">XQuery 1.0 and + * XPath 2.0 Data Model, 5.15 typed-value Accessor</a> + */ + Item::Iterator::Ptr sequencedTypedValue() const; + + /** + * @short Determines whether this item is an atomic value, or a node. + * + * If this Item is @c null, @c false is returned. + * + * @see isNode() + * @returns @c true if it is an atomic value, otherwise @c false. + */ + inline bool isAtomicValue() const + { + /* Setting node.model to ~0, signals that it's an atomic value. */ + return node.model == reinterpret_cast<QAbstractXmlNodeModel *>(~0); + } + + /** + * @short Determines whether this item is an atomic value, or a node. + * + * If this Item is @c null, false is returned. + * + * @see isAtomicValue() + * @returns @c true if this item is a node, otherwise @c false. + */ + inline bool isNode() const + { + //return !isAtomicValue(); + return node.model && node.model != reinterpret_cast<QAbstractXmlNodeModel *>(~0); + } + + /** + * @short Returns the ItemType this Item is of. + * + * For example, if this Item is an XML node, more specifically a text node, + * <tt>text()</tt> is returned. That is, BuiltinTypes::text. However, if this + * Item is an atomic value of type <tt>xs:long</tt> that is what's returned, + * BuiltinTypes::xsLong. + * + * @returns the type of this Item. + */ + inline QExplicitlySharedDataPointer<ItemType> type() const + { + if(isAtomicValue()) + return atomicValue->type(); + else + return asNode().type(); + } + + inline const AtomicValue *asAtomicValue() const + { + Q_ASSERT(isAtomicValue()); + return atomicValue; + } + + inline const QXmlNodeModelIndex &asNode() const + { + Q_ASSERT_X(isNode() || isNull(), Q_FUNC_INFO, + "This item isn't a valid QXmlNodeModelIndex."); + Q_ASSERT_X(sizeof(QXmlNodeModelIndex) == sizeof(QPatternist::NodeIndexStorage), Q_FUNC_INFO, + "If this doesn't hold, something is wrong."); + + return reinterpret_cast<const QXmlNodeModelIndex &>(node); + } + + inline operator bool() const + { + return node.model; + } + + inline bool isNull() const + { + return !node.model; + } + + inline void reset() + { + /* Note that this function should be equal to the default + * constructor. */ + node.model = 0; + node.data = 0; + } + + static inline Item fromPublic(const QXmlItem &i) + { + const Item it(i.m_node); + if(it.isAtomicValue()) + it.asAtomicValue()->ref.ref(); + + return it; + } + + static inline QXmlItem toPublic(const Item &i) + { + return QXmlItem(i); + } + + private: + union + { + NodeIndexStorage node; + const AtomicValue *atomicValue; + }; + }; + + template<typename T> + inline Item toItem(const QExplicitlySharedDataPointer<T> atomicValue) + { + return Item(atomicValue.data()); + } + + /** + * This is an overload, provided for convenience. + * @relates QXmlNodeModelIndex + */ + static inline QString formatData(const QXmlNodeModelIndex node) + { + return node.stringValue(); // This can be improved a lot. + } +} + + inline QXmlName QXmlNodeModelIndex::name() const + { + return m_storage.model->name(*this); + } + + inline QXmlNodeModelIndex QXmlNodeModelIndex::root() const + { + return m_storage.model->root(*this); + } + + inline QXmlNodeModelIndex::Iterator::Ptr QXmlNodeModelIndex::iterate(const QXmlNodeModelIndex::Axis axis) const + { + return m_storage.model->iterate(*this, axis); + } + + inline QUrl QXmlNodeModelIndex::documentUri() const + { + return m_storage.model->documentUri(*this); + } + + inline QUrl QXmlNodeModelIndex::baseUri() const + { + return m_storage.model->baseUri(*this); + } + + inline QXmlNodeModelIndex::NodeKind QXmlNodeModelIndex::kind() const + { + return m_storage.model->kind(*this); + } + + inline bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const + { + return m_storage.model->isDeepEqual(*this, other); + } + + inline QXmlNodeModelIndex::DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const + { + Q_ASSERT_X(model() == other.model(), Q_FUNC_INFO, "The API docs guarantees the two nodes are from the same model"); + return m_storage.model->compareOrder(*this, other); + } + + inline bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const + { + return m_storage.model == other.m_storage.model && + m_storage.data == other.m_storage.data && + m_storage.additionalData == other.m_storage.additionalData; + } + + inline void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const + { + m_storage.model->sendNamespaces(*this, receiver); + } + + inline QVector<QXmlName> QXmlNodeModelIndex::namespaceBindings() const + { + return m_storage.model->namespaceBindings(*this); + } + + inline QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const + { + return m_storage.model->namespaceForPrefix(*this, prefix); + } + + inline QString QXmlNodeModelIndex::stringValue() const + { + return m_storage.model->stringValue(*this); + } + + inline QPatternist::ItemType::Ptr QXmlNodeModelIndex::type() const + { + return m_storage.model->type(*this); + } + + inline QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > QXmlNodeModelIndex::sequencedTypedValue() const + { + return m_storage.model->sequencedTypedValue(*this); + } + + inline QXmlItem::QXmlItem(const QPatternist::Item &i) : m_node(i.node) + { + if(isAtomicValue()) + m_atomicValue->ref.ref(); + } + +Q_DECLARE_TYPEINFO(QPatternist::Item::Iterator::Ptr, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QPatternist::AtomicValue, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif |