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/HashTraits.h> 25 #include <wtf/text/AtomicString.h> 26 27 namespace WebCore { 28 29 struct QualifiedNameComponents { 30 StringImpl* m_prefix; 31 StringImpl* m_localName; 32 StringImpl* m_namespace; 33 }; 34 35 class QualifiedName { 36 WTF_MAKE_FAST_ALLOCATED; 37 public: 38 class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> { 39 public: 40 static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI) 41 { 42 return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI)); 43 } 44 45 const AtomicString m_prefix; 46 const AtomicString m_localName; 47 const AtomicString m_namespace; 48 mutable AtomicString m_localNameUpper; 49 50 private: 51 QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI) 52 : m_prefix(prefix) 53 , m_localName(localName) 54 , m_namespace(namespaceURI) 55 { 56 ASSERT(!namespaceURI.isEmpty() || namespaceURI.isNull()); 57 } 58 }; 59 60 QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI); 61 QualifiedName(const AtomicString& prefix, const char* localName, const AtomicString& namespaceURI); 62 QualifiedName(WTF::HashTableDeletedValueType) : m_impl(hashTableDeletedValue()) { } 63 bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); } 64 ~QualifiedName(); 65 #ifdef QNAME_DEFAULT_CONSTRUCTOR 66 QualifiedName() : m_impl(0) { } 67 #endif 68 69 QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { ref(); } 70 const QualifiedName& operator=(const QualifiedName& other) { other.ref(); deref(); m_impl = other.m_impl; return *this; } 71 72 bool operator==(const QualifiedName& other) const { return m_impl == other.m_impl; } 73 bool operator!=(const QualifiedName& other) const { return !(*this == other); } 74 75 bool matches(const QualifiedName& other) const { return m_impl == other.m_impl || (localName() == other.localName() && namespaceURI() == other.namespaceURI()); } 76 77 bool hasPrefix() const { return m_impl->m_prefix != nullAtom; } 78 void setPrefix(const AtomicString& prefix) { *this = QualifiedName(prefix, localName(), namespaceURI()); } 79 80 const AtomicString& prefix() const { return m_impl->m_prefix; } 81 const AtomicString& localName() const { return m_impl->m_localName; } 82 const AtomicString& namespaceURI() const { return m_impl->m_namespace; } 83 84 // Uppercased localName, cached for efficiency 85 const AtomicString& localNameUpper() const; 86 87 String toString() const; 88 89 QualifiedNameImpl* impl() const { return m_impl; } 90 91 // Init routine for globals 92 static void init(); 93 94 private: 95 void init(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI); 96 void ref() const { m_impl->ref(); } 97 void deref(); 98 99 static QualifiedNameImpl* hashTableDeletedValue() { return RefPtr<QualifiedNameImpl>::hashTableDeletedValue(); } 100 101 QualifiedNameImpl* m_impl; 102 }; 103 104 #ifndef WEBCORE_QUALIFIEDNAME_HIDE_GLOBALS 105 extern const QualifiedName anyName; 106 inline const QualifiedName& anyQName() { return anyName; } 107 #endif 108 109 inline bool operator==(const AtomicString& a, const QualifiedName& q) { return a == q.localName(); } 110 inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a != q.localName(); } 111 inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); } 112 inline bool operator!=(const QualifiedName& q, const AtomicString& a) { return a != q.localName(); } 113 114 inline unsigned hashComponents(const QualifiedNameComponents& buf) 115 { 116 return StringHasher::hashMemory<sizeof(QualifiedNameComponents)>(&buf); 117 } 118 119 struct QualifiedNameHash { 120 static unsigned hash(const QualifiedName& name) { return hash(name.impl()); } 121 122 static unsigned hash(const QualifiedName::QualifiedNameImpl* name) 123 { 124 QualifiedNameComponents c = { name->m_prefix.impl(), name->m_localName.impl(), name->m_namespace.impl() }; 125 return hashComponents(c); 126 } 127 128 static bool equal(const QualifiedName& a, const QualifiedName& b) { return a == b; } 129 static bool equal(const QualifiedName::QualifiedNameImpl* a, const QualifiedName::QualifiedNameImpl* b) { return a == b; } 130 131 static const bool safeToCompareToEmptyOrDeleted = false; 132 }; 133 134 } 135 136 namespace WTF { 137 138 template<typename T> struct DefaultHash; 139 140 template<> struct DefaultHash<WebCore::QualifiedName> { 141 typedef WebCore::QualifiedNameHash Hash; 142 }; 143 144 template<> struct HashTraits<WebCore::QualifiedName> : SimpleClassHashTraits<WebCore::QualifiedName> { 145 static const bool emptyValueIsZero = false; 146 static WebCore::QualifiedName emptyValue() { return WebCore::QualifiedName(nullAtom, nullAtom, nullAtom); } 147 }; 148 } 149 150 #endif 151