15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005, 2006, 2009 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef QualifiedName_h 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define QualifiedName_h 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 240019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch#include "wtf/HashTableDeletedValueType.h" 25e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/HashTraits.h" 26e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/RefCounted.h" 27e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/AtomicString.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct QualifiedNameComponents { 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl* m_prefix; 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl* m_localName; 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl* m_namespace; 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)// This struct is used to pass data between QualifiedName and the QNameTranslator. 385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)// For hashing and equality only the QualifiedNameComponents fields are used. 395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)struct QualifiedNameData { 405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) QualifiedNameComponents m_components; 415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) bool m_isStatic; 425d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)}; 435d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class QualifiedName { 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WTF_MAKE_FAST_ALLOCATED; 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> { 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI, bool isStatic) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 515d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI, isStatic)); 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ~QualifiedNameImpl(); 55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned computeHash() const; 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 585d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) void ref() 595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) { 605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (m_isStatic) 615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefCounted<QualifiedNameImpl>::ref(); 635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) void deref() 665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) { 675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (m_isStatic) 685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefCounted<QualifiedNameImpl>::deref(); 705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // We rely on StringHasher's hashMemory clearing out the top 8 bits when 735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // doing hashing and use one of the bits for the m_isStatic value. 745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) mutable unsigned m_existingHash : 24; 755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) unsigned m_isStatic : 1; 767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const AtomicString m_prefix; 777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const AtomicString m_localName; 787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const AtomicString m_namespace; 797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci mutable AtomicString m_localNameUpper; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private: 825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI, bool isStatic) 837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci : m_existingHash(0) 847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_isStatic(isStatic) 857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_prefix(prefix) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_localName(localName) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_namespace(namespaceURI) 885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!namespaceURI.isEmpty() || namespaceURI.isNull()); 9102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch } 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ~QualifiedName(); 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { } 9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const QualifiedName& operator=(const QualifiedName& other) { m_impl = other.m_impl; return *this; } 9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Hash table deleted values, which are only constructed and never copied or destroyed. 10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) QualifiedName(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { } 10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); } 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool operator==(const QualifiedName& other) const { return m_impl == other.m_impl; } 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool operator!=(const QualifiedName& other) const { return !(*this == other); } 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool matches(const QualifiedName& other) const { return m_impl == other.m_impl || (localName() == other.localName() && namespaceURI() == other.namespaceURI()); } 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 109e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) bool matchesPossiblyIgnoringCase(const QualifiedName& other, bool shouldIgnoreCase) const { return m_impl == other.m_impl || (equalPossiblyIgnoringCase(localName(), other.localName(), shouldIgnoreCase) && namespaceURI() == other.namespaceURI()); } 110e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool hasPrefix() const { return m_impl->m_prefix != nullAtom; } 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setPrefix(const AtomicString& prefix) { *this = QualifiedName(prefix, localName(), namespaceURI()); } 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const AtomicString& prefix() const { return m_impl->m_prefix; } 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const AtomicString& localName() const { return m_impl->m_localName; } 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const AtomicString& namespaceURI() const { return m_impl->m_namespace; } 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Uppercased localName, cached for efficiency 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const AtomicString& localNameUpper() const; 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String toString() const; 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) QualifiedNameImpl* impl() const { return m_impl.get(); } 12402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Init routine for globals 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static void init(); 12702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) static const QualifiedName& null(); 1295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 1305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // The below methods are only for creating static global QNames that need no ref counting. 1315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) static void createStatic(void* targetAddress, StringImpl* name); 1325d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) static void createStatic(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace); 1335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 1355d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // This constructor is used only to create global/static QNames that don't require any ref counting. 1365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI, bool isStatic); 1375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RefPtr<QualifiedNameImpl> m_impl; 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 141c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)extern const QualifiedName& anyName; 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline const QualifiedName& anyQName() { return anyName; } 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator==(const AtomicString& a, const QualifiedName& q) { return a == q.localName(); } 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a != q.localName(); } 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); } 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator!=(const QualifiedName& q, const AtomicString& a) { return a != q.localName(); } 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline unsigned hashComponents(const QualifiedNameComponents& buf) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return StringHasher::hashMemory<sizeof(QualifiedNameComponents)>(&buf); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct QualifiedNameHash { 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static unsigned hash(const QualifiedName& name) { return hash(name.impl()); } 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch static unsigned hash(const QualifiedName::QualifiedNameImpl* name) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!name->m_existingHash) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) name->m_existingHash = name->computeHash(); 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return name->m_existingHash; 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static bool equal(const QualifiedName& a, const QualifiedName& b) { return a == b; } 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static bool equal(const QualifiedName::QualifiedNameImpl* a, const QualifiedName::QualifiedNameImpl* b) { return a == b; } 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static const bool safeToCompareToEmptyOrDeleted = false; 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 170e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} // namespace blink 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WTF { 17302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) template<typename T> struct DefaultHash; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) template<> struct DefaultHash<blink::QualifiedName> { 177c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) typedef blink::QualifiedNameHash Hash; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 17902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 180c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) template<> struct HashTraits<blink::QualifiedName> : SimpleClassHashTraits<blink::QualifiedName> { 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static const bool emptyValueIsZero = false; 182c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) static blink::QualifiedName emptyValue() { return blink::QualifiedName::null(); } 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 187