Home | History | Annotate | Download | only in dom
      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