| 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 | #include <QtDebug> |
| 41 | |
| 42 | #include "private/qxmlutils_p.h" |
| 43 | #include "qxpathhelper_p.h" |
| 44 | |
| 45 | #include "qnamepool_p.h" |
| 46 | |
| 47 | QT_BEGIN_NAMESPACE |
| 48 | |
| 49 | using namespace QPatternist; |
| 50 | |
| 51 | NamePool::NamePool() |
| 52 | { |
| 53 | m_localNameMapping .reserve(asize: DefaultLocalNameCapacity + StandardLocalNameCount); |
| 54 | m_localNames .reserve(asize: DefaultLocalNameCapacity + StandardLocalNameCount); |
| 55 | m_namespaceMapping .reserve(asize: DefaultURICapacity + StandardNamespaceCount); |
| 56 | m_namespaces .reserve(asize: DefaultURICapacity + StandardNamespaceCount); |
| 57 | m_prefixes .reserve(asize: DefaultPrefixCapacity + StandardPrefixCount); |
| 58 | m_prefixMapping .reserve(asize: DefaultPrefixCapacity + StandardPrefixCount); |
| 59 | |
| 60 | /* Namespaces. */ |
| 61 | { |
| 62 | unlockedAllocateNamespace(uri: QString()); |
| 63 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2005/xpath-functions" )); |
| 64 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2005/xquery-local-functions" )); |
| 65 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/XML/1998/namespace" )); |
| 66 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2000/xmlns/" )); |
| 67 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2001/XMLSchema" )); |
| 68 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2001/XMLSchema-instance" )); |
| 69 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/1999/XSL/Transform" )); |
| 70 | |
| 71 | /* For UndeclarePrefix, StopNamespaceInheritance and InternalXSLT. We use two |
| 72 | * arbitrary strings that aren't used. For instance, if we just used an |
| 73 | * empty QString, unlockedAllocateNamespace() would assign it |
| 74 | * StandardNamespaces::empty. However, it's important that the string |
| 75 | * is an invalid namespace, since otherwise user strings would get |
| 76 | * assigned the same IDs. */ |
| 77 | unlockedAllocateNamespace(uri: QLatin1String(" | 1 " )); |
| 78 | unlockedAllocateNamespace(uri: QLatin1String(" | 2 " )); |
| 79 | unlockedAllocateNamespace(uri: QLatin1String(" | InternalXSLT" )); |
| 80 | |
| 81 | Q_ASSERT_X(m_namespaces.count() == StandardNamespaceCount, Q_FUNC_INFO, |
| 82 | qPrintable(QString::fromLatin1("Expected is %1, actual is %2." ).arg(StandardNamespaceCount).arg(m_namespaces.count()))); |
| 83 | } |
| 84 | |
| 85 | /* Prefixes. */ |
| 86 | { |
| 87 | unlockedAllocatePrefix(prefix: QString()); |
| 88 | unlockedAllocatePrefix(prefix: QLatin1String("fn" )); |
| 89 | unlockedAllocatePrefix(prefix: QLatin1String("local" )); |
| 90 | unlockedAllocatePrefix(prefix: QLatin1String("xml" )); |
| 91 | unlockedAllocatePrefix(prefix: QLatin1String("xmlns" )); |
| 92 | unlockedAllocatePrefix(prefix: QLatin1String("xs" )); |
| 93 | unlockedAllocatePrefix(prefix: QLatin1String("xsi" )); |
| 94 | unlockedAllocatePrefix(prefix: QLatin1String("ns0" )); |
| 95 | unlockedAllocatePrefix(prefix: QLatin1String("|||" )); /* Invalid NCName, for StopNamespaceInheritance. */ |
| 96 | |
| 97 | Q_ASSERT_X(m_prefixes.count() == StandardPrefixCount, Q_FUNC_INFO, |
| 98 | qPrintable(QString::fromLatin1("Expected is %1, actual is %2." ).arg(StandardPrefixCount).arg(m_prefixes.count()))); |
| 99 | } |
| 100 | |
| 101 | /* Local names. */ |
| 102 | { |
| 103 | /* Same order as the enum in StandardLocalNames. That is, alphabetically. */ |
| 104 | unlockedAllocateLocalName(ln: QLatin1String("abs" )); |
| 105 | unlockedAllocateLocalName(ln: QLatin1String("adjust-dateTime-to-timezone" )); |
| 106 | unlockedAllocateLocalName(ln: QLatin1String("adjust-date-to-timezone" )); |
| 107 | unlockedAllocateLocalName(ln: QLatin1String("adjust-time-to-timezone" )); |
| 108 | unlockedAllocateLocalName(ln: QLatin1String("all" )); |
| 109 | unlockedAllocateLocalName(ln: QLatin1String("arity" )); |
| 110 | unlockedAllocateLocalName(ln: QLatin1String("avg" )); |
| 111 | unlockedAllocateLocalName(ln: QLatin1String("base" )); |
| 112 | unlockedAllocateLocalName(ln: QLatin1String("base-uri" )); |
| 113 | unlockedAllocateLocalName(ln: QLatin1String("boolean" )); |
| 114 | unlockedAllocateLocalName(ln: QLatin1String("ceiling" )); |
| 115 | unlockedAllocateLocalName(ln: QLatin1String("codepoint-equal" )); |
| 116 | unlockedAllocateLocalName(ln: QLatin1String("codepoints-to-string" )); |
| 117 | unlockedAllocateLocalName(ln: QLatin1String("collection" )); |
| 118 | unlockedAllocateLocalName(ln: QLatin1String("compare" )); |
| 119 | unlockedAllocateLocalName(ln: QLatin1String("concat" )); |
| 120 | unlockedAllocateLocalName(ln: QLatin1String("contains" )); |
| 121 | unlockedAllocateLocalName(ln: QLatin1String("count" )); |
| 122 | unlockedAllocateLocalName(ln: QLatin1String("current" )); |
| 123 | unlockedAllocateLocalName(ln: QLatin1String("current-date" )); |
| 124 | unlockedAllocateLocalName(ln: QLatin1String("current-dateTime" )); |
| 125 | unlockedAllocateLocalName(ln: QLatin1String("current-time" )); |
| 126 | unlockedAllocateLocalName(ln: QLatin1String("data" )); |
| 127 | unlockedAllocateLocalName(ln: QLatin1String("dateTime" )); |
| 128 | unlockedAllocateLocalName(ln: QLatin1String("day-from-date" )); |
| 129 | unlockedAllocateLocalName(ln: QLatin1String("day-from-dateTime" )); |
| 130 | unlockedAllocateLocalName(ln: QLatin1String("days-from-duration" )); |
| 131 | unlockedAllocateLocalName(ln: QLatin1String("deep-equal" )); |
| 132 | unlockedAllocateLocalName(ln: QLatin1String("default" )); |
| 133 | unlockedAllocateLocalName(ln: QLatin1String("default-collation" )); |
| 134 | unlockedAllocateLocalName(ln: QLatin1String("distinct-values" )); |
| 135 | unlockedAllocateLocalName(ln: QLatin1String("doc" )); |
| 136 | unlockedAllocateLocalName(ln: QLatin1String("doc-available" )); |
| 137 | unlockedAllocateLocalName(ln: QLatin1String("document" )); |
| 138 | unlockedAllocateLocalName(ln: QLatin1String("document-uri" )); |
| 139 | unlockedAllocateLocalName(ln: QLatin1String("element-available" )); |
| 140 | unlockedAllocateLocalName(ln: QLatin1String("empty" )); |
| 141 | unlockedAllocateLocalName(ln: QLatin1String("encode-for-uri" )); |
| 142 | unlockedAllocateLocalName(ln: QLatin1String("ends-with" )); |
| 143 | unlockedAllocateLocalName(ln: QLatin1String("error" )); |
| 144 | unlockedAllocateLocalName(ln: QLatin1String("escape-html-uri" )); |
| 145 | unlockedAllocateLocalName(ln: QLatin1String("exactly-one" )); |
| 146 | unlockedAllocateLocalName(ln: QLatin1String("exists" )); |
| 147 | unlockedAllocateLocalName(ln: QLatin1String("false" )); |
| 148 | unlockedAllocateLocalName(ln: QLatin1String("floor" )); |
| 149 | unlockedAllocateLocalName(ln: QLatin1String("function-available" )); |
| 150 | unlockedAllocateLocalName(ln: QLatin1String("function-name" )); |
| 151 | unlockedAllocateLocalName(ln: QLatin1String("generate-id" )); |
| 152 | unlockedAllocateLocalName(ln: QLatin1String("generic-string-join" )); |
| 153 | unlockedAllocateLocalName(ln: QLatin1String("hours-from-dateTime" )); |
| 154 | unlockedAllocateLocalName(ln: QLatin1String("hours-from-duration" )); |
| 155 | unlockedAllocateLocalName(ln: QLatin1String("hours-from-time" )); |
| 156 | unlockedAllocateLocalName(ln: QLatin1String("id" )); |
| 157 | unlockedAllocateLocalName(ln: QLatin1String("idref" )); |
| 158 | unlockedAllocateLocalName(ln: QLatin1String("implicit-timezone" )); |
| 159 | unlockedAllocateLocalName(ln: QLatin1String("index-of" )); |
| 160 | unlockedAllocateLocalName(ln: QLatin1String("in-scope-prefixes" )); |
| 161 | unlockedAllocateLocalName(ln: QLatin1String("insert-before" )); |
| 162 | unlockedAllocateLocalName(ln: QLatin1String("iri-to-uri" )); |
| 163 | unlockedAllocateLocalName(ln: QLatin1String("is-schema-aware" )); |
| 164 | unlockedAllocateLocalName(ln: QLatin1String("key" )); |
| 165 | unlockedAllocateLocalName(ln: QLatin1String("lang" )); |
| 166 | unlockedAllocateLocalName(ln: QLatin1String("last" )); |
| 167 | unlockedAllocateLocalName(ln: QLatin1String("local-name" )); |
| 168 | unlockedAllocateLocalName(ln: QLatin1String("local-name-from-QName" )); |
| 169 | unlockedAllocateLocalName(ln: QLatin1String("lower-case" )); |
| 170 | unlockedAllocateLocalName(ln: QLatin1String("matches" )); |
| 171 | unlockedAllocateLocalName(ln: QLatin1String("max" )); |
| 172 | unlockedAllocateLocalName(ln: QLatin1String("min" )); |
| 173 | unlockedAllocateLocalName(ln: QLatin1String("minutes-from-dateTime" )); |
| 174 | unlockedAllocateLocalName(ln: QLatin1String("minutes-from-duration" )); |
| 175 | unlockedAllocateLocalName(ln: QLatin1String("minutes-from-time" )); |
| 176 | unlockedAllocateLocalName(ln: QLatin1String("month-from-date" )); |
| 177 | unlockedAllocateLocalName(ln: QLatin1String("month-from-dateTime" )); |
| 178 | unlockedAllocateLocalName(ln: QLatin1String("months-from-duration" )); |
| 179 | unlockedAllocateLocalName(ln: QLatin1String("name" )); |
| 180 | unlockedAllocateLocalName(ln: QLatin1String("namespace-uri" )); |
| 181 | unlockedAllocateLocalName(ln: QLatin1String("namespace-uri-for-prefix" )); |
| 182 | unlockedAllocateLocalName(ln: QLatin1String("namespace-uri-from-QName" )); |
| 183 | unlockedAllocateLocalName(ln: QLatin1String("nilled" )); |
| 184 | unlockedAllocateLocalName(ln: QLatin1String("node-name" )); |
| 185 | unlockedAllocateLocalName(ln: QLatin1String("normalize-space" )); |
| 186 | unlockedAllocateLocalName(ln: QLatin1String("normalize-unicode" )); |
| 187 | unlockedAllocateLocalName(ln: QLatin1String("not" )); |
| 188 | unlockedAllocateLocalName(ln: QLatin1String("number" )); |
| 189 | unlockedAllocateLocalName(ln: QLatin1String("one-or-more" )); |
| 190 | unlockedAllocateLocalName(ln: QLatin1String("position" )); |
| 191 | unlockedAllocateLocalName(ln: QLatin1String("prefix-from-QName" )); |
| 192 | unlockedAllocateLocalName(ln: QLatin1String("product-name" )); |
| 193 | unlockedAllocateLocalName(ln: QLatin1String("product-version" )); |
| 194 | unlockedAllocateLocalName(ln: QLatin1String("property-name" )); |
| 195 | unlockedAllocateLocalName(ln: QLatin1String("QName" )); |
| 196 | unlockedAllocateLocalName(ln: QLatin1String("remove" )); |
| 197 | unlockedAllocateLocalName(ln: QLatin1String("replace" )); |
| 198 | unlockedAllocateLocalName(ln: QLatin1String("resolve-QName" )); |
| 199 | unlockedAllocateLocalName(ln: QLatin1String("resolve-uri" )); |
| 200 | unlockedAllocateLocalName(ln: QLatin1String("reverse" )); |
| 201 | unlockedAllocateLocalName(ln: QLatin1String("root" )); |
| 202 | unlockedAllocateLocalName(ln: QLatin1String("round" )); |
| 203 | unlockedAllocateLocalName(ln: QLatin1String("round-half-to-even" )); |
| 204 | unlockedAllocateLocalName(ln: QLatin1String("seconds-from-dateTime" )); |
| 205 | unlockedAllocateLocalName(ln: QLatin1String("seconds-from-duration" )); |
| 206 | unlockedAllocateLocalName(ln: QLatin1String("seconds-from-time" )); |
| 207 | unlockedAllocateLocalName(ln: QLatin1String("sourceValue" )); |
| 208 | unlockedAllocateLocalName(ln: QLatin1String("starts-with" )); |
| 209 | unlockedAllocateLocalName(ln: QLatin1String("static-base-uri" )); |
| 210 | unlockedAllocateLocalName(ln: QLatin1String("string" )); |
| 211 | unlockedAllocateLocalName(ln: QLatin1String("string-join" )); |
| 212 | unlockedAllocateLocalName(ln: QLatin1String("string-length" )); |
| 213 | unlockedAllocateLocalName(ln: QLatin1String("string-to-codepoints" )); |
| 214 | unlockedAllocateLocalName(ln: QLatin1String("subsequence" )); |
| 215 | unlockedAllocateLocalName(ln: QLatin1String("substring" )); |
| 216 | unlockedAllocateLocalName(ln: QLatin1String("substring-after" )); |
| 217 | unlockedAllocateLocalName(ln: QLatin1String("substring-before" )); |
| 218 | unlockedAllocateLocalName(ln: QLatin1String("sum" )); |
| 219 | unlockedAllocateLocalName(ln: QLatin1String("supports-backwards-compatibility" )); |
| 220 | unlockedAllocateLocalName(ln: QLatin1String("supports-serialization" )); |
| 221 | unlockedAllocateLocalName(ln: QLatin1String("system-property" )); |
| 222 | unlockedAllocateLocalName(ln: QLatin1String("timezone-from-date" )); |
| 223 | unlockedAllocateLocalName(ln: QLatin1String("timezone-from-dateTime" )); |
| 224 | unlockedAllocateLocalName(ln: QLatin1String("timezone-from-time" )); |
| 225 | unlockedAllocateLocalName(ln: QLatin1String("tokenize" )); |
| 226 | unlockedAllocateLocalName(ln: QLatin1String("trace" )); |
| 227 | unlockedAllocateLocalName(ln: QLatin1String("translate" )); |
| 228 | unlockedAllocateLocalName(ln: QLatin1String("true" )); |
| 229 | unlockedAllocateLocalName(ln: QLatin1String("type-available" )); |
| 230 | unlockedAllocateLocalName(ln: QLatin1String("unordered" )); |
| 231 | unlockedAllocateLocalName(ln: QLatin1String("unparsed-entity-public-id" )); |
| 232 | unlockedAllocateLocalName(ln: QLatin1String("unparsed-entity-uri" )); |
| 233 | unlockedAllocateLocalName(ln: QLatin1String("unparsed-text" )); |
| 234 | unlockedAllocateLocalName(ln: QLatin1String("unparsed-text-available" )); |
| 235 | unlockedAllocateLocalName(ln: QLatin1String("upper-case" )); |
| 236 | unlockedAllocateLocalName(ln: QLatin1String("vendor" )); |
| 237 | unlockedAllocateLocalName(ln: QLatin1String("vendor-url" )); |
| 238 | unlockedAllocateLocalName(ln: QLatin1String("version" )); |
| 239 | unlockedAllocateLocalName(ln: QLatin1String("xml" )); |
| 240 | unlockedAllocateLocalName(ln: QLatin1String("xmlns" )); |
| 241 | unlockedAllocateLocalName(ln: QLatin1String("year-from-date" )); |
| 242 | unlockedAllocateLocalName(ln: QLatin1String("year-from-dateTime" )); |
| 243 | unlockedAllocateLocalName(ln: QLatin1String("years-from-duration" )); |
| 244 | unlockedAllocateLocalName(ln: QLatin1String("zero-or-one" )); |
| 245 | Q_ASSERT(m_localNames.count() == StandardLocalNameCount); |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | QXmlName NamePool::allocateQName(const QString &uri, const QString &localName, const QString &prefix) |
| 250 | { |
| 251 | QWriteLocker l(&lock); |
| 252 | |
| 253 | /* |
| 254 | QString codepoints; |
| 255 | for(int i = 0; i < localName.length(); ++i) |
| 256 | codepoints.append(QString::number(localName.at(i).unicode()) + QLatin1Char(' ')); |
| 257 | |
| 258 | pDebug() << Q_FUNC_INFO << localName << "codepoints:" << codepoints; |
| 259 | */ |
| 260 | |
| 261 | Q_ASSERT_X(QXmlUtils::isNCName(localName), Q_FUNC_INFO, |
| 262 | qPrintable(QString::fromLatin1("'%1' is an invalid NCName." ).arg(localName))); |
| 263 | |
| 264 | const QXmlName::NamespaceCode nsCode = unlockedAllocateNamespace(uri); |
| 265 | const QXmlName::LocalNameCode localCode = unlockedAllocateLocalName(ln: localName); |
| 266 | |
| 267 | Q_ASSERT(prefix.isEmpty() || QXmlUtils::isNCName(prefix)); |
| 268 | const QXmlName::PrefixCode prefixCode = unlockedAllocatePrefix(prefix); |
| 269 | |
| 270 | return QXmlName(nsCode, localCode, prefixCode); |
| 271 | } |
| 272 | |
| 273 | QXmlName NamePool::allocateBinding(const QString &prefix, const QString &uri) |
| 274 | { |
| 275 | QWriteLocker l(&lock); |
| 276 | |
| 277 | Q_ASSERT_X(prefix.isEmpty() || QXmlUtils::isNCName(prefix), Q_FUNC_INFO, |
| 278 | qPrintable(QString::fromLatin1("%1 is an invalid prefix." ).arg(prefix))); |
| 279 | const QXmlName::NamespaceCode nsCode = unlockedAllocateNamespace(uri); |
| 280 | |
| 281 | Q_ASSERT(prefix.isEmpty() || QXmlUtils::isNCName(prefix)); |
| 282 | const QXmlName::PrefixCode prefixCode = unlockedAllocatePrefix(prefix); |
| 283 | |
| 284 | return QXmlName(nsCode, StandardLocalNames::empty, prefixCode); |
| 285 | } |
| 286 | |
| 287 | QXmlName::LocalNameCode NamePool::unlockedAllocateLocalName(const QString &ln) |
| 288 | { |
| 289 | Q_ASSERT_X(QXmlUtils::isNCName(ln), Q_FUNC_INFO, |
| 290 | qPrintable(QString::fromLatin1("Invalid local name: \"%1\"" ).arg(ln))); |
| 291 | |
| 292 | int indexInLocalNames = m_localNameMapping.value(akey: ln, adefaultValue: NoSuchValue); |
| 293 | |
| 294 | if(indexInLocalNames == NoSuchValue) |
| 295 | { |
| 296 | indexInLocalNames = m_localNames.count(); |
| 297 | m_localNames.append(t: ln); |
| 298 | m_localNameMapping.insert(akey: ln, avalue: indexInLocalNames); |
| 299 | } |
| 300 | |
| 301 | return indexInLocalNames; |
| 302 | } |
| 303 | |
| 304 | QXmlName::PrefixCode NamePool::unlockedAllocatePrefix(const QString &prefix) |
| 305 | { |
| 306 | int indexInPrefixes = m_prefixMapping.value(akey: prefix, adefaultValue: NoSuchValue); |
| 307 | |
| 308 | if(indexInPrefixes == NoSuchValue) |
| 309 | { |
| 310 | indexInPrefixes = m_prefixes.count(); |
| 311 | m_prefixes.append(t: prefix); |
| 312 | m_prefixMapping.insert(akey: prefix, avalue: indexInPrefixes); |
| 313 | } |
| 314 | |
| 315 | return indexInPrefixes; |
| 316 | } |
| 317 | |
| 318 | QXmlName::NamespaceCode NamePool::unlockedAllocateNamespace(const QString &uri) |
| 319 | { |
| 320 | int indexInURIs = m_namespaceMapping.value(akey: uri, adefaultValue: NoSuchValue); |
| 321 | |
| 322 | if(indexInURIs == NoSuchValue) |
| 323 | { |
| 324 | indexInURIs = m_namespaces.count(); |
| 325 | m_namespaces.append(t: uri); |
| 326 | m_namespaceMapping.insert(akey: uri, avalue: indexInURIs); |
| 327 | } |
| 328 | |
| 329 | return indexInURIs; |
| 330 | } |
| 331 | |
| 332 | const QString &NamePool::displayPrefix(const QXmlName::NamespaceCode nc) const |
| 333 | { |
| 334 | switch(nc) |
| 335 | { |
| 336 | case StandardNamespaces::xmlns: return m_prefixes.at(i: StandardPrefixes::xmlns); |
| 337 | case StandardNamespaces::local: return m_prefixes.at(i: StandardPrefixes::local); |
| 338 | case StandardNamespaces::xs: return m_prefixes.at(i: StandardPrefixes::xs); |
| 339 | case StandardNamespaces::xml: return m_prefixes.at(i: StandardPrefixes::xml); |
| 340 | case StandardNamespaces::fn: return m_prefixes.at(i: StandardPrefixes::fn); |
| 341 | default: return m_prefixes.at(i: StandardPrefixes::empty); |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | QString NamePool::displayName(const QXmlName qName) const |
| 346 | { |
| 347 | QReadLocker l(&lock); |
| 348 | |
| 349 | if(qName.hasNamespace()) |
| 350 | { |
| 351 | if(qName.namespaceURI() == StandardNamespaces::InternalXSLT) |
| 352 | return QLatin1Char('#') + m_localNames.at(i: qName.localName()); |
| 353 | |
| 354 | const QString &p = displayPrefix(nc: qName.namespaceURI()); |
| 355 | |
| 356 | if(p.isEmpty()) |
| 357 | return QLatin1Char('{') + m_namespaces.at(i: qName.namespaceURI()) + QLatin1Char('}') + toLexical(qName); |
| 358 | else |
| 359 | return p + QLatin1Char(':') + m_localNames.at(i: qName.localName()); |
| 360 | } |
| 361 | else |
| 362 | return m_localNames.at(i: qName.localName()); |
| 363 | } |
| 364 | |
| 365 | QString NamePool::toClarkName(const QXmlName &name) const |
| 366 | { |
| 367 | if(name.isNull()) |
| 368 | return QLatin1String("QXmlName(null)" ); |
| 369 | else |
| 370 | { |
| 371 | if(name.hasNamespace()) |
| 372 | { |
| 373 | const QString ns(stringForNamespace(code: name.namespaceURI())); |
| 374 | const QString p(stringForPrefix(code: name.prefix())); |
| 375 | const QString l(stringForLocalName(code: name.localName())); |
| 376 | |
| 377 | return QChar::fromLatin1(c: '{') |
| 378 | + ns |
| 379 | + QChar::fromLatin1(c: '}') |
| 380 | + (p.isEmpty() ? l : p + QChar::fromLatin1(c: ':') + l); |
| 381 | } |
| 382 | else |
| 383 | return stringForLocalName(code: name.localName()); |
| 384 | } |
| 385 | } |
| 386 | |
| 387 | QXmlName NamePool::fromClarkName(const QString &clarkName) |
| 388 | { |
| 389 | if(clarkName.isEmpty()) |
| 390 | return QXmlName(); |
| 391 | |
| 392 | if(clarkName.at(i: 0) == QLatin1Char('{')) |
| 393 | { |
| 394 | const int indexOfRight = clarkName.indexOf(c: QLatin1Char('}')); |
| 395 | const QString qName(clarkName.right(n: (clarkName.length() - indexOfRight) - 1)); |
| 396 | |
| 397 | if(!XPathHelper::isQName(qName)) |
| 398 | return QXmlName(); |
| 399 | |
| 400 | QString localName; |
| 401 | QString prefix; |
| 402 | |
| 403 | XPathHelper::splitQName(qName, prefix, localName); |
| 404 | |
| 405 | return allocateQName(uri: clarkName.mid(position: 1, n: indexOfRight - 1), |
| 406 | localName, prefix); |
| 407 | } |
| 408 | else |
| 409 | { |
| 410 | if(QXmlName::isNCName(candidate: clarkName)) |
| 411 | return allocateQName(uri: QString(), localName: clarkName); |
| 412 | else |
| 413 | return QXmlName(); |
| 414 | } |
| 415 | } |
| 416 | QT_END_NAMESPACE |
| 417 | |