summaryrefslogtreecommitdiff
path: root/src/xmlpatterns/utils/qnamepool_p.h
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commite1b2c9deb5943faae2b29be6a5c006f75bb73f06 (patch)
treefc79e45367c0a8fc71185e9afc33f7503a58653c /src/xmlpatterns/utils/qnamepool_p.h
downloadqtxmlpatterns-e1b2c9deb5943faae2b29be6a5c006f75bb73f06.tar.gz
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/xmlpatterns/utils/qnamepool_p.h')
-rw-r--r--src/xmlpatterns/utils/qnamepool_p.h556
1 files changed, 556 insertions, 0 deletions
diff --git a/src/xmlpatterns/utils/qnamepool_p.h b/src/xmlpatterns/utils/qnamepool_p.h
new file mode 100644
index 0000000..8d1beb9
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamepool_p.h
@@ -0,0 +1,556 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NamePool_H
+#define Patternist_NamePool_H
+
+#include <QHash>
+#include <QReadLocker>
+#include <QReadWriteLock>
+#include <QSharedData>
+#include <QString>
+#include <QVector>
+#include <QXmlName>
+
+#include <QtXmlPatterns/private/qprimitives_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Store names such as namespace bindings and QNames and allows them to
+ * be referenced in efficient ways.
+ *
+ * Once a string have been inserted it stays there and cannot be removed. The
+ * only way to deallocate any string in the NamePool is to deallocate the
+ * NamePool itself, as a whole.
+ *
+ * This class is not only reentrant, it is thread-safe in all sense of the
+ * word. All functions of this class can be called concurrently. This is
+ * achieved by internal locking.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo Use QSubStrings, we can save very many heap allocations by that.
+ * @todo Check limits
+ */
+ class Q_AUTOTEST_EXPORT NamePool : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<NamePool> Ptr;
+
+ private:
+ friend class StandardNamespaces;
+
+ enum
+ {
+ NoSuchValue = -1,
+ /**
+ * This must be identical to the amount of members in
+ * StandardNamespaces.
+ */
+ StandardNamespaceCount = 11,
+ StandardPrefixCount = 9,
+ StandardLocalNameCount = 141
+ };
+
+ QVector<QString> m_prefixes;
+ QVector<QString> m_namespaces;
+ QVector<QString> m_localNames;
+
+ /**
+ * This hash contains no essential data, but speeds up
+ * finding a prefix in m_prefixes by mapping a prefix(the key) to
+ * the index into m_prefixes(which the value is).
+ *
+ * In other words, one can skip this variable at the cost of having
+ * to linearly loop over prefixes, in order to find the entry.
+ */
+ QHash<QString, QXmlName::PrefixCode> m_prefixMapping;
+
+ /**
+ * Same as m_prefixMapping but applies for URIs, and hence m_namespaces instead
+ * of m_prefixes.
+ */
+ QHash<QString, QXmlName::NamespaceCode> m_namespaceMapping;
+
+ QHash<QString, QXmlName::LocalNameCode> m_localNameMapping;
+
+ enum DefaultCapacities
+ {
+ DefaultPrefixCapacity = 10,
+ DefaultURICapacity = DefaultPrefixCapacity,
+ /**
+ * It looks like it's quite common with 40-60 different local names per XML
+ * vocabulary. For background, see:
+ *
+ * - http://englich.wordpress.com/2007/01/11/representing-xml/
+ * - http://englich.wordpress.com/2007/01/09/xmlstat/
+ */
+ DefaultLocalNameCapacity = 60
+ };
+
+ public:
+ NamePool();
+
+ /**
+ * @short Allocates a namespace binding for @p prefix and @p uri.
+ *
+ * In the returned QXmlName, the local name is
+ * StandardLocalNames::empty, and QXmlName::prefix() and
+ * QXmlName::namespaceUri() returns @p prefix and @p uri, respectively.
+ *
+ * In older versions of this code, the class NamespaceBinding existed,
+ * but as part of having the public class QXmlName, it was dropped and
+ * a special interpretation/convention involving use of QXmlName was
+ * adopted.
+ */
+ QXmlName allocateBinding(const QString &prefix, const QString &uri);
+
+ QXmlName allocateQName(const QString &uri, const QString &localName, const QString &prefix = QString());
+
+ inline QXmlName allocateQName(const QXmlName::NamespaceCode uri, const QString &ln)
+ {
+ /* We don't lock here, but we do in allocateLocalName(). */
+ return QXmlName(uri, allocateLocalName(ln));
+ }
+
+ inline const QString &stringForLocalName(const QXmlName::LocalNameCode code) const
+ {
+ const QReadLocker l(&lock);
+ return m_localNames.at(code);
+ }
+
+ inline const QString &stringForPrefix(const QXmlName::PrefixCode code) const
+ {
+ const QReadLocker l(&lock);
+ return m_prefixes.at(code);
+ }
+
+ inline const QString &stringForNamespace(const QXmlName::NamespaceCode code) const
+ {
+ const QReadLocker l(&lock);
+ return m_namespaces.at(code);
+ }
+
+ QString displayName(const QXmlName qName) const;
+
+ inline QString toLexical(const QXmlName qName) const
+ {
+ const QReadLocker l(&lock);
+ Q_ASSERT_X(!qName.isNull(), "", "It makes no sense to call toLexical() on a null name.");
+
+ if(qName.hasPrefix())
+ {
+ const QString &p = m_prefixes.at(qName.prefix());
+ return p + QLatin1Char(':') + m_localNames.at(qName.localName());
+ }
+ else
+ return m_localNames.at(qName.localName());
+ }
+
+ inline QXmlName::NamespaceCode allocateNamespace(const QString &uri)
+ {
+ const QWriteLocker l(&lock);
+ return unlockedAllocateNamespace(uri);
+ }
+
+ inline QXmlName::LocalNameCode allocateLocalName(const QString &ln)
+ {
+ const QWriteLocker l(&lock);
+ return unlockedAllocateLocalName(ln);
+ }
+
+ inline QXmlName::PrefixCode allocatePrefix(const QString &prefix)
+ {
+ const QWriteLocker l(&lock);
+ return unlockedAllocatePrefix(prefix);
+ }
+
+ QString toClarkName(const QXmlName &name) const;
+ QXmlName fromClarkName(const QString &clarkName);
+
+ private:
+ /**
+ * @note This function can not be called concurrently.
+ */
+ QXmlName::NamespaceCode unlockedAllocateNamespace(const QString &uri);
+
+ /**
+ * @note This function can not be called concurrently.
+ */
+ QXmlName::LocalNameCode unlockedAllocateLocalName(const QString &ln);
+
+ /**
+ * It's assumed that @p prefix is a valid @c NCName.
+ *
+ * @note This function can not be called concurrently.
+ */
+ QXmlName::PrefixCode unlockedAllocatePrefix(const QString &prefix);
+
+ Q_DISABLE_COPY(NamePool)
+
+ /**
+ * @note This function can not be called concurrently.
+ */
+ const QString &displayPrefix(const QXmlName::NamespaceCode nc) const;
+
+ mutable QReadWriteLock lock;
+ };
+
+ /**
+ * @short Formats QName.
+ *
+ * @relates QXmlName
+ */
+ static inline QString formatKeyword(const NamePool::Ptr &np, const QXmlName name)
+ {
+ return QLatin1String("<span class='XQuery-keyword'>") +
+ escape(np->displayName(name)) +
+ QLatin1String("</span>");
+ }
+
+ /**
+ * @see NamespaceResolver::Constants
+ */
+ class StandardNamespaces
+ {
+ public:
+ enum ID
+ {
+ /**
+ * This does not mean empty in the sense of "empty", but
+ * in the sense of an empty string, "".
+ *
+ * Its value, zero, is significant.
+ */
+ empty = 0,
+ fn,
+ local,
+ xml,
+ xmlns,
+ xs,
+ xsi,
+ xslt,
+ /**
+ * @short A special value that when passed as the namespace part
+ * to NamespaceResolver::addBinding(), undeclares the prefix.
+ *
+ * This is used by the namespace prolog declaration.
+ *
+ * A dummy value is added to the name pool.
+ */
+ UndeclarePrefix,
+
+ /**
+ * Signals that a node shouldn't inherit namespaces from its parent. Must be used
+ * with StandardPrefixes::StopNamespaceInheritance.
+ */
+ StopNamespaceInheritance,
+
+ /**
+ * A namespace used to identify for instance @c \#all template
+ * mode in XSL-T.
+ */
+ InternalXSLT
+ };
+ };
+
+ // const QString * a = &*qset.insert("foo");
+ class StandardLocalNames
+ {
+ public:
+ enum
+ {
+ abs,
+ adjust_dateTime_to_timezone,
+ adjust_date_to_timezone,
+ adjust_time_to_timezone,
+ all,
+ arity,
+ avg,
+ base,
+ base_uri,
+ boolean,
+ ceiling,
+ codepoint_equal,
+ codepoints_to_string,
+ collection,
+ compare,
+ concat,
+ contains,
+ count,
+ current,
+ current_date,
+ current_dateTime,
+ current_time,
+ data,
+ dateTime,
+ day_from_date,
+ day_from_dateTime,
+ days_from_duration,
+ deep_equal,
+ Default,
+ default_collation,
+ distinct_values,
+ doc,
+ doc_available,
+ document,
+ document_uri,
+ element_available,
+ empty,
+ encode_for_uri,
+ ends_with,
+ error,
+ escape_html_uri,
+ exactly_one,
+ exists,
+ False,
+ floor,
+ function_available,
+ function_name,
+ generate_id,
+ generic_string_join,
+ hours_from_dateTime,
+ hours_from_duration,
+ hours_from_time,
+ id,
+ idref,
+ implicit_timezone,
+ index_of,
+ in_scope_prefixes,
+ insert_before,
+ iri_to_uri,
+ is_schema_aware,
+ key,
+ lang,
+ last,
+ local_name,
+ local_name_from_QName,
+ lower_case,
+ matches,
+ max,
+ min,
+ minutes_from_dateTime,
+ minutes_from_duration,
+ minutes_from_time,
+ month_from_date,
+ month_from_dateTime,
+ months_from_duration,
+ name,
+ namespace_uri,
+ namespace_uri_for_prefix,
+ namespace_uri_from_QName,
+ nilled,
+ node_name,
+ normalize_space,
+ normalize_unicode,
+ Not,
+ number,
+ one_or_more,
+ position,
+ prefix_from_QName,
+ product_name,
+ product_version,
+ property_name,
+ QName,
+ remove,
+ replace,
+ resolve_QName,
+ resolve_uri,
+ reverse,
+ root,
+ round,
+ round_half_to_even,
+ seconds_from_dateTime,
+ seconds_from_duration,
+ seconds_from_time,
+ sourceValue,
+ starts_with,
+ static_base_uri,
+ string,
+ string_join,
+ string_length,
+ string_to_codepoints,
+ subsequence,
+ substring,
+ substring_after,
+ substring_before,
+ sum,
+ supports_backwards_compatibility,
+ supports_serialization,
+ system_property,
+ timezone_from_date,
+ timezone_from_dateTime,
+ timezone_from_time,
+ tokenize,
+ trace,
+ translate,
+ True,
+ type_available,
+ unordered,
+ unparsed_entity_public_id,
+ unparsed_entity_uri,
+ unparsed_text,
+ unparsed_text_available,
+ upper_case,
+ vendor,
+ vendor_url,
+ version,
+ xml,
+ xmlns,
+ year_from_date,
+ year_from_dateTime,
+ years_from_duration,
+ zero_or_one
+ };
+ };
+
+ class StandardPrefixes
+ {
+ public:
+ enum
+ {
+ /**
+ * This does not mean empty in the sense of "empty", but
+ * in the sense of an empty string, "".
+ *
+ * Its value, zero, is significant.
+ */
+ empty = 0,
+ fn,
+ local,
+ xml,
+ xmlns,
+ xs,
+ xsi,
+ ns0,
+ StopNamespaceInheritance
+ };
+ };
+}
+
+inline QXmlName::LocalNameCode QXmlName::localName() const
+{
+ return (m_qNameCode & LocalNameMask) >> LocalNameOffset;
+}
+
+inline QXmlName::PrefixCode QXmlName::prefix() const
+{
+ return (m_qNameCode & PrefixMask) >> PrefixOffset;
+}
+
+inline bool QXmlName::hasPrefix() const
+{
+ return prefix() != 0;
+}
+
+inline bool QXmlName::hasNamespace() const
+{
+ return namespaceURI() != 0;
+}
+
+inline QXmlName::NamespaceCode QXmlName::namespaceURI() const
+{
+ return (m_qNameCode & NamespaceMask) >> NamespaceOffset;
+}
+
+inline bool QXmlName::isLexicallyEqual(const QXmlName &other) const
+{
+ return (m_qNameCode & LexicalQNameMask) == (other.m_qNameCode & LexicalQNameMask);
+}
+
+inline void QXmlName::setPrefix(const PrefixCode c)
+{
+ m_qNameCode |= (c << PrefixOffset);
+}
+
+inline void QXmlName::setNamespaceURI(const NamespaceCode c)
+{
+ m_qNameCode |= (c << NamespaceOffset);
+}
+
+inline void QXmlName::setLocalName(const LocalNameCode c)
+{
+ m_qNameCode |= (c << LocalNameOffset);
+}
+
+inline QXmlName::Code QXmlName::code() const
+{
+ return m_qNameCode;
+}
+
+inline QXmlName::QXmlName(const NamespaceCode uri,
+ const LocalNameCode ln,
+ const PrefixCode p) : m_qNameCode((uri << NamespaceOffset) +
+ (ln << LocalNameOffset) +
+ (p << PrefixOffset))
+{
+ /* We can't use members like prefix() here because if one of the
+ * values are to large, they would overflow into the others. */
+ Q_ASSERT_X(p <= MaximumPrefixes, "",
+ qPrintable(QString::fromLatin1("NamePool prefix limits: max is %1, therefore %2 exceeds.").arg(MaximumPrefixes).arg(p)));
+ Q_ASSERT_X(ln <= MaximumLocalNames, "",
+ qPrintable(QString::fromLatin1("NamePool local name limits: max is %1, therefore %2 exceeds.").arg(MaximumLocalNames).arg(ln)));
+ Q_ASSERT_X(uri <= MaximumNamespaces, "",
+ qPrintable(QString::fromLatin1("NamePool namespace limits: max is %1, therefore %2 exceeds.").arg(MaximumNamespaces).arg(uri)));
+}
+
+
+Q_DECLARE_TYPEINFO(QPatternist::NamePool::Ptr, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif