1 /* 2 * Copyright (C) 2005, 2006, 2009 Apple Inc. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 * 19 */ 20 21 #ifndef QualifiedName_h 22 #define QualifiedName_h 23 24 #include "wtf/Forward.h" 25 #include "wtf/HashTableDeletedValueType.h" 26 #include "wtf/HashTraits.h" 27 #include "wtf/RefCounted.h" 28 #include "wtf/text/AtomicString.h" 29 30 namespace WebCore { 31 32 struct QualifiedNameComponents { 33 StringImpl* m_prefix; 34 StringImpl* m_localName; 35 StringImpl* m_namespace; 36 }; 37 38 class QualifiedName { 39 WTF_MAKE_FAST_ALLOCATED; 40 public: 41 class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> { 42 public: 43 static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI) 44 { 45 return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI)); 46 } 47 48 ~QualifiedNameImpl(); 49 50 unsigned computeHash() const; 51 52 mutable unsigned m_existingHash; 53 const AtomicString m_prefix; 54 const AtomicString m_localName; 55 const AtomicString m_namespace; 56 mutable AtomicString m_localNameUpper; 57 58 private: 59 QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI) 60 : m_existingHash(0) 61 , m_prefix(prefix) 62 , m_localName(localName) 63 , m_namespace(namespaceURI) 64 { 65 ASSERT(!namespaceURI.isEmpty() || namespaceURI.isNull()); 66 } 67 }; 68 69 QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI); 70 QualifiedName(WTF::HashTableDeletedValueType) : m_impl(hashTableDeletedValue()) { } 71 bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); } 72 ~QualifiedName(); 73 #ifdef QNAME_DEFAULT_CONSTRUCTOR 74 QualifiedName() : m_impl(0) { } 75 #endif 76 77 QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { ref(); } 78 const QualifiedName& operator=(const QualifiedName& other) { other.ref(); deref(); m_impl = other.m_impl; return *this; } 79 80 bool operator==(const QualifiedName& other) const { return m_impl == other.m_impl; } 81 bool operator!=(const QualifiedName& other) const { return !(*this == other); } 82 83 bool matches(const QualifiedName& other) const { return m_impl == other.m_impl || (localName() == other.localName() && namespaceURI() == other.namespaceURI()); } 84 85 bool matchesPossiblyIgnoringCase(const QualifiedName& other, bool shouldIgnoreCase) const { return m_impl == other.m_impl || (equalPossiblyIgnoringCase(localName(), other.localName(), shouldIgnoreCase) && namespaceURI() == other.namespaceURI()); } 86 87 bool hasPrefix() const { return m_impl->m_prefix != nullAtom; } 88 void setPrefix(const AtomicString& prefix) { *this = QualifiedName(prefix, localName(), namespaceURI()); } 89 90 const AtomicString& prefix() const { return m_impl->m_prefix; } 91 const AtomicString& localName() const { return m_impl->m_localName; } 92 const AtomicString& namespaceURI() const { return m_impl->m_namespace; } 93 94 // Uppercased localName, cached for efficiency 95 const AtomicString& localNameUpper() const; 96 97 String toString() const; 98 99 QualifiedNameImpl* impl() const { return m_impl; } 100 101 // Init routine for globals 102 static void init(); 103 104 private: 105 void ref() const { m_impl->ref(); } 106 void deref(); 107 108 static QualifiedNameImpl* hashTableDeletedValue() { return RefPtr<QualifiedNameImpl>::hashTableDeletedValue(); } 109 110 QualifiedNameImpl* m_impl; 111 }; 112 113 #ifndef WEBCORE_QUALIFIEDNAME_HIDE_GLOBALS 114 extern const QualifiedName anyName; 115 inline const QualifiedName& anyQName() { return anyName; } 116 #endif 117 118 const QualifiedName& nullQName(); 119 120 inline bool operator==(const AtomicString& a, const QualifiedName& q) { return a == q.localName(); } 121 inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a != q.localName(); } 122 inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); } 123 inline bool operator!=(const QualifiedName& q, const AtomicString& a) { return a != q.localName(); } 124 125 inline unsigned hashComponents(const QualifiedNameComponents& buf) 126 { 127 return StringHasher::hashMemory<sizeof(QualifiedNameComponents)>(&buf); 128 } 129 130 struct QualifiedNameHash { 131 static unsigned hash(const QualifiedName& name) { return hash(name.impl()); } 132 133 static unsigned hash(const QualifiedName::QualifiedNameImpl* name) 134 { 135 if (!name->m_existingHash) 136 name->m_existingHash = name->computeHash(); 137 return name->m_existingHash; 138 } 139 140 static bool equal(const QualifiedName& a, const QualifiedName& b) { return a == b; } 141 static bool equal(const QualifiedName::QualifiedNameImpl* a, const QualifiedName::QualifiedNameImpl* b) { return a == b; } 142 143 static const bool safeToCompareToEmptyOrDeleted = false; 144 }; 145 146 void createQualifiedName(void* targetAddress, StringImpl* name); 147 void createQualifiedName(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace); 148 149 } 150 151 namespace WTF { 152 153 template<typename T> struct DefaultHash; 154 155 template<> struct DefaultHash<WebCore::QualifiedName> { 156 typedef WebCore::QualifiedNameHash Hash; 157 }; 158 159 template<> struct HashTraits<WebCore::QualifiedName> : SimpleClassHashTraits<WebCore::QualifiedName> { 160 static const bool emptyValueIsZero = false; 161 static WebCore::QualifiedName emptyValue() { return WebCore::nullQName(); } 162 }; 163 } 164 165 #endif 166