Qt 4.8
qnamepool.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <QtDebug>
43 
44 #include "private/qxmlutils_p.h"
45 #include "qxpathhelper_p.h"
46 
47 #include "qnamepool_p.h"
48 
50 
51 using namespace QPatternist;
52 
54 {
61 
62  /* Namespaces. */
63  {
65  unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2005/xpath-functions"));
66  unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2005/xquery-local-functions"));
67  unlockedAllocateNamespace(QLatin1String("http://www.w3.org/XML/1998/namespace"));
68  unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2000/xmlns/"));
69  unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2001/XMLSchema"));
70  unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"));
71  unlockedAllocateNamespace(QLatin1String("http://www.w3.org/1999/XSL/Transform"));
72 
73  /* For UndeclarePrefix, StopNamespaceInheritance and InternalXSLT. We use two
74  * arbitrary strings that aren't used. For instance, if we just used an
75  * empty QString, unlockedAllocateNamespace() would assign it
76  * StandardNamespaces::empty. However, it's important that the string
77  * is an invalid namespace, since otherwise user strings would get
78  * assigned the same IDs. */
81  unlockedAllocateNamespace(QLatin1String(" | InternalXSLT"));
82 
84  qPrintable(QString::fromLatin1("Expected is %1, actual is %2.").arg(StandardNamespaceCount).arg(m_namespaces.count())));
85  }
86 
87  /* Prefixes. */
88  {
97  unlockedAllocatePrefix(QLatin1String("|||")); /* Invalid NCName, for StopNamespaceInheritance. */
98 
100  qPrintable(QString::fromLatin1("Expected is %1, actual is %2.").arg(StandardPrefixCount).arg(m_prefixes.count())));
101  }
102 
103  /* Local names. */
104  {
105  /* Same order as the enum in StandardLocalNames. That is, alphabetically. */
107  unlockedAllocateLocalName(QLatin1String("adjust-dateTime-to-timezone"));
108  unlockedAllocateLocalName(QLatin1String("adjust-date-to-timezone"));
109  unlockedAllocateLocalName(QLatin1String("adjust-time-to-timezone"));
117  unlockedAllocateLocalName(QLatin1String("codepoint-equal"));
118  unlockedAllocateLocalName(QLatin1String("codepoints-to-string"));
125  unlockedAllocateLocalName(QLatin1String("current-date"));
126  unlockedAllocateLocalName(QLatin1String("current-dateTime"));
127  unlockedAllocateLocalName(QLatin1String("current-time"));
130  unlockedAllocateLocalName(QLatin1String("day-from-date"));
131  unlockedAllocateLocalName(QLatin1String("day-from-dateTime"));
132  unlockedAllocateLocalName(QLatin1String("days-from-duration"));
135  unlockedAllocateLocalName(QLatin1String("default-collation"));
136  unlockedAllocateLocalName(QLatin1String("distinct-values"));
138  unlockedAllocateLocalName(QLatin1String("doc-available"));
140  unlockedAllocateLocalName(QLatin1String("document-uri"));
141  unlockedAllocateLocalName(QLatin1String("element-available"));
143  unlockedAllocateLocalName(QLatin1String("encode-for-uri"));
146  unlockedAllocateLocalName(QLatin1String("escape-html-uri"));
151  unlockedAllocateLocalName(QLatin1String("function-available"));
152  unlockedAllocateLocalName(QLatin1String("function-name"));
154  unlockedAllocateLocalName(QLatin1String("generic-string-join"));
155  unlockedAllocateLocalName(QLatin1String("hours-from-dateTime"));
156  unlockedAllocateLocalName(QLatin1String("hours-from-duration"));
157  unlockedAllocateLocalName(QLatin1String("hours-from-time"));
160  unlockedAllocateLocalName(QLatin1String("implicit-timezone"));
162  unlockedAllocateLocalName(QLatin1String("in-scope-prefixes"));
163  unlockedAllocateLocalName(QLatin1String("insert-before"));
165  unlockedAllocateLocalName(QLatin1String("is-schema-aware"));
170  unlockedAllocateLocalName(QLatin1String("local-name-from-QName"));
175  unlockedAllocateLocalName(QLatin1String("minutes-from-dateTime"));
176  unlockedAllocateLocalName(QLatin1String("minutes-from-duration"));
177  unlockedAllocateLocalName(QLatin1String("minutes-from-time"));
178  unlockedAllocateLocalName(QLatin1String("month-from-date"));
179  unlockedAllocateLocalName(QLatin1String("month-from-dateTime"));
180  unlockedAllocateLocalName(QLatin1String("months-from-duration"));
182  unlockedAllocateLocalName(QLatin1String("namespace-uri"));
183  unlockedAllocateLocalName(QLatin1String("namespace-uri-for-prefix"));
184  unlockedAllocateLocalName(QLatin1String("namespace-uri-from-QName"));
187  unlockedAllocateLocalName(QLatin1String("normalize-space"));
188  unlockedAllocateLocalName(QLatin1String("normalize-unicode"));
193  unlockedAllocateLocalName(QLatin1String("prefix-from-QName"));
194  unlockedAllocateLocalName(QLatin1String("product-name"));
195  unlockedAllocateLocalName(QLatin1String("product-version"));
196  unlockedAllocateLocalName(QLatin1String("property-name"));
200  unlockedAllocateLocalName(QLatin1String("resolve-QName"));
205  unlockedAllocateLocalName(QLatin1String("round-half-to-even"));
206  unlockedAllocateLocalName(QLatin1String("seconds-from-dateTime"));
207  unlockedAllocateLocalName(QLatin1String("seconds-from-duration"));
208  unlockedAllocateLocalName(QLatin1String("seconds-from-time"));
211  unlockedAllocateLocalName(QLatin1String("static-base-uri"));
214  unlockedAllocateLocalName(QLatin1String("string-length"));
215  unlockedAllocateLocalName(QLatin1String("string-to-codepoints"));
218  unlockedAllocateLocalName(QLatin1String("substring-after"));
219  unlockedAllocateLocalName(QLatin1String("substring-before"));
221  unlockedAllocateLocalName(QLatin1String("supports-backwards-compatibility"));
222  unlockedAllocateLocalName(QLatin1String("supports-serialization"));
223  unlockedAllocateLocalName(QLatin1String("system-property"));
224  unlockedAllocateLocalName(QLatin1String("timezone-from-date"));
225  unlockedAllocateLocalName(QLatin1String("timezone-from-dateTime"));
226  unlockedAllocateLocalName(QLatin1String("timezone-from-time"));
231  unlockedAllocateLocalName(QLatin1String("type-available"));
233  unlockedAllocateLocalName(QLatin1String("unparsed-entity-public-id"));
234  unlockedAllocateLocalName(QLatin1String("unparsed-entity-uri"));
235  unlockedAllocateLocalName(QLatin1String("unparsed-text"));
236  unlockedAllocateLocalName(QLatin1String("unparsed-text-available"));
243  unlockedAllocateLocalName(QLatin1String("year-from-date"));
244  unlockedAllocateLocalName(QLatin1String("year-from-dateTime"));
245  unlockedAllocateLocalName(QLatin1String("years-from-duration"));
248  }
249 }
250 
251 QXmlName NamePool::allocateQName(const QString &uri, const QString &localName, const QString &prefix)
252 {
253  QWriteLocker l(&lock);
254 
255  /*
256  QString codepoints;
257  for(int i = 0; i < localName.length(); ++i)
258  codepoints.append(QString::number(localName.at(i).unicode()) + QLatin1Char(' '));
259 
260  pDebug() << Q_FUNC_INFO << localName << "codepoints:" << codepoints;
261  */
262 
264  qPrintable(QString::fromLatin1("'%1' is an invalid NCName.").arg(localName)));
265 
267  const QXmlName::LocalNameCode localCode = unlockedAllocateLocalName(localName);
268 
269  Q_ASSERT(prefix.isEmpty() || QXmlUtils::isNCName(prefix));
270  const QXmlName::PrefixCode prefixCode = unlockedAllocatePrefix(prefix);
271 
272  return QXmlName(nsCode, localCode, prefixCode);
273 }
274 
276 {
277  QWriteLocker l(&lock);
278 
279  Q_ASSERT_X(prefix.isEmpty() || QXmlUtils::isNCName(prefix), Q_FUNC_INFO,
280  qPrintable(QString::fromLatin1("%1 is an invalid prefix.").arg(prefix)));
282 
283  Q_ASSERT(prefix.isEmpty() || QXmlUtils::isNCName(prefix));
284  const QXmlName::PrefixCode prefixCode = unlockedAllocatePrefix(prefix);
285 
286  return QXmlName(nsCode, StandardLocalNames::empty, prefixCode);
287 }
288 
290 {
292  qPrintable(QString::fromLatin1("Invalid local name: \"%1\"").arg(ln)));
293 
294  int indexInLocalNames = m_localNameMapping.value(ln, NoSuchValue);
295 
296  if(indexInLocalNames == NoSuchValue)
297  {
298  indexInLocalNames = m_localNames.count();
299  m_localNames.append(ln);
300  m_localNameMapping.insert(ln, indexInLocalNames);
301  }
302 
303  return indexInLocalNames;
304 }
305 
307 {
308  int indexInPrefixes = m_prefixMapping.value(prefix, NoSuchValue);
309 
310  if(indexInPrefixes == NoSuchValue)
311  {
312  indexInPrefixes = m_prefixes.count();
313  m_prefixes.append(prefix);
314  m_prefixMapping.insert(prefix, indexInPrefixes);
315  }
316 
317  return indexInPrefixes;
318 }
319 
321 {
322  int indexInURIs = m_namespaceMapping.value(uri, NoSuchValue);
323 
324  if(indexInURIs == NoSuchValue)
325  {
326  indexInURIs = m_namespaces.count();
327  m_namespaces.append(uri);
328  m_namespaceMapping.insert(uri, indexInURIs);
329  }
330 
331  return indexInURIs;
332 }
333 
335 {
336  switch(nc)
337  {
343  default: return m_prefixes.at(StandardPrefixes::empty);
344  }
345 }
346 
348 {
349  QReadLocker l(&lock);
350 
351  if(qName.hasNamespace())
352  {
354  return QLatin1Char('#') + m_localNames.at(qName.localName());
355 
356  const QString &p = displayPrefix(qName.namespaceURI());
357 
358  if(p.isEmpty())
359  return QLatin1Char('{') + m_namespaces.at(qName.namespaceURI()) + QLatin1Char('}') + toLexical(qName);
360  else
361  return p + QLatin1Char(':') + m_localNames.at(qName.localName());
362  }
363  else
364  return m_localNames.at(qName.localName());
365 }
366 
368 {
369  if(name.isNull())
370  return QLatin1String("QXmlName(null)");
371  else
372  {
373  if(name.hasNamespace())
374  {
375  const QString ns(stringForNamespace(name.namespaceURI()));
376  const QString p(stringForPrefix(name.prefix()));
377  const QString l(stringForLocalName(name.localName()));
378 
379  return QChar::fromLatin1('{')
380  + ns
381  + QChar::fromLatin1('}')
382  + (p.isEmpty() ? l : p + QChar::fromLatin1(':') + l);
383  }
384  else
385  return stringForLocalName(name.localName());
386  }
387 }
388 
390 {
391  if(clarkName.isEmpty())
392  return QXmlName();
393 
394  if(clarkName.at(0) == QLatin1Char('{'))
395  {
396  const int indexOfRight = clarkName.indexOf(QLatin1Char('}'));
397  const QString qName(clarkName.right((clarkName.length() - indexOfRight) - 1));
398 
399  if(!XPathHelper::isQName(qName))
400  return QXmlName();
401 
402  QString localName;
403  QString prefix;
404 
405  XPathHelper::splitQName(qName, prefix, localName);
406 
407  return allocateQName(clarkName.mid(1, indexOfRight - 1),
408  localName, prefix);
409  }
410  else
411  {
412  if(QXmlName::isNCName(clarkName))
413  return allocateQName(QString(), clarkName);
414  else
415  return QXmlName();
416  }
417 }
const QString & stringForLocalName(const QXmlName::LocalNameCode code) const
Definition: qnamepool_p.h:168
QString displayName(const QXmlName qName) const
Definition: qnamepool.cpp:347
QHash< QString, QXmlName::PrefixCode > m_prefixMapping
Definition: qnamepool_p.h:119
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
bool hasNamespace() const
Returns true if this QXmlName has a non-empty namespace URI.
Definition: qnamepool_p.h:498
NamespaceCode LocalNameCode
Definition: qxmlname.h:84
QHash< QString, QXmlName::LocalNameCode > m_localNameMapping
Definition: qnamepool_p.h:127
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
QXmlName allocateBinding(const QString &prefix, const QString &uri)
Allocates a namespace binding for prefix and uri.
Definition: qnamepool.cpp:275
qint16 NamespaceCode
Definition: qxmlname.h:82
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QVector< QString > m_localNames
Definition: qnamepool_p.h:109
The QString class provides a Unicode character string.
Definition: qstring.h:83
QXmlName fromClarkName(const QString &clarkName)
Definition: qnamepool.cpp:389
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QXmlName::LocalNameCode unlockedAllocateLocalName(const QString &ln)
Definition: qnamepool.cpp:289
QHash< QString, QXmlName::NamespaceCode > m_namespaceMapping
Definition: qnamepool_p.h:125
QString prefix(const QXmlNamePool &query) const
Returns the prefix.
Definition: qxmlname.cpp:370
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
void reserve(int size)
Ensures that the QHash&#39;s internal hash table consists of at least size buckets.
Definition: qhash.h:846
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
const QString & stringForPrefix(const QXmlName::PrefixCode code) const
Definition: qnamepool_p.h:174
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
const char * name
The namespace for the internal API of QtXmlPatterns.
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
QVector< QString > m_namespaces
Definition: qnamepool_p.h:108
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
static QChar fromLatin1(char c)
Converts the Latin-1 character c to its equivalent QChar.
Definition: qchar.h:378
QString right(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n rightmost characters of the string.
Definition: qstring.cpp:3682
QXmlName::NamespaceCode unlockedAllocateNamespace(const QString &uri)
Definition: qnamepool.cpp:320
The QReadLocker class is a convenience class that simplifies locking and unlocking read-write locks f...
QReadWriteLock lock
Definition: qnamepool_p.h:248
The QWriteLocker class is a convenience class that simplifies locking and unlocking read-write locks ...
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QVector< QString > m_prefixes
Definition: qnamepool_p.h:107
QString localName(const QXmlNamePool &query) const
Returns the local name.
Definition: qxmlname.cpp:387
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
NamespaceCode namespaceURI() const
Definition: qnamepool_p.h:503
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
QString toClarkName(const QXmlName &name) const
Definition: qnamepool.cpp:367
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
static bool isNCName(const QString &candidate)
Returns true if candidate is an NCName.
Definition: qxmlname.cpp:445
const QString & stringForNamespace(const QXmlName::NamespaceCode code) const
Definition: qnamepool_p.h:180
QXmlName allocateQName(const QString &uri, const QString &localName, const QString &prefix=QString())
Definition: qnamepool.cpp:251
static void splitQName(const QString &qName, QString &prefix, QString &localName)
Splits qName into localName and prefix.
QFactoryLoader * l
void reserve(int size)
Attempts to allocate memory for at least size elements.
Definition: qvector.h:339
QString toLexical(const QXmlName qName) const
Definition: qnamepool_p.h:188
static bool isQName(const QString &qName)
#define qPrintable(string)
Definition: qglobal.h:1750
const QString & displayPrefix(const QXmlName::NamespaceCode nc) const
Definition: qnamepool.cpp:334
static bool isNCName(const QStringRef &ncName)
Determines whether c is a valid instance of production [4]NCName in the XML 1.0 Namespaces specificat...
Definition: qxmlutils.cpp:377
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
bool isNull() const
Returns true if this QXmlName is not initialized with a valid combination of {namespace URI}...
Definition: qxmlname.cpp:224
QXmlName::PrefixCode unlockedAllocatePrefix(const QString &prefix)
Definition: qnamepool.cpp:306
#define Q_FUNC_INFO
Definition: qglobal.h:1871
NamespaceCode PrefixCode
Definition: qxmlname.h:83