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 hasPrefix() const { return m_impl->m_prefix != nullAtom; }
     86     void setPrefix(const AtomicString& prefix) { *this = QualifiedName(prefix, localName(), namespaceURI()); }
     87 
     88     const AtomicString& prefix() const { return m_impl->m_prefix; }
     89     const AtomicString& localName() const { return m_impl->m_localName; }
     90     const AtomicString& namespaceURI() const { return m_impl->m_namespace; }
     91 
     92     // Uppercased localName, cached for efficiency
     93     const AtomicString& localNameUpper() const;
     94 
     95     String toString() const;
     96 
     97     QualifiedNameImpl* impl() const { return m_impl; }
     98 
     99     // Init routine for globals
    100     static void init();
    101 
    102 private:
    103     void ref() const { m_impl->ref(); }
    104     void deref();
    105 
    106     static QualifiedNameImpl* hashTableDeletedValue() { return RefPtr<QualifiedNameImpl>::hashTableDeletedValue(); }
    107 
    108     QualifiedNameImpl* m_impl;
    109 };
    110 
    111 #ifndef WEBCORE_QUALIFIEDNAME_HIDE_GLOBALS
    112 extern const QualifiedName anyName;
    113 inline const QualifiedName& anyQName() { return anyName; }
    114 #endif
    115 
    116 const QualifiedName& nullQName();
    117 
    118 inline bool operator==(const AtomicString& a, const QualifiedName& q) { return a == q.localName(); }
    119 inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a != q.localName(); }
    120 inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); }
    121 inline bool operator!=(const QualifiedName& q, const AtomicString& a) { return a != q.localName(); }
    122 
    123 inline unsigned hashComponents(const QualifiedNameComponents& buf)
    124 {
    125     return StringHasher::hashMemory<sizeof(QualifiedNameComponents)>(&buf);
    126 }
    127 
    128 struct QualifiedNameHash {
    129     static unsigned hash(const QualifiedName& name) { return hash(name.impl()); }
    130 
    131     static unsigned hash(const QualifiedName::QualifiedNameImpl* name)
    132     {
    133         if (!name->m_existingHash)
    134             name->m_existingHash = name->computeHash();
    135         return name->m_existingHash;
    136     }
    137 
    138     static bool equal(const QualifiedName& a, const QualifiedName& b) { return a == b; }
    139     static bool equal(const QualifiedName::QualifiedNameImpl* a, const QualifiedName::QualifiedNameImpl* b) { return a == b; }
    140 
    141     static const bool safeToCompareToEmptyOrDeleted = false;
    142 };
    143 
    144 void createQualifiedName(void* targetAddress, StringImpl* name);
    145 void createQualifiedName(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace);
    146 
    147 }
    148 
    149 namespace WTF {
    150 
    151     template<typename T> struct DefaultHash;
    152 
    153     template<> struct DefaultHash<WebCore::QualifiedName> {
    154         typedef WebCore::QualifiedNameHash Hash;
    155     };
    156 
    157     template<> struct HashTraits<WebCore::QualifiedName> : SimpleClassHashTraits<WebCore::QualifiedName> {
    158         static const bool emptyValueIsZero = false;
    159         static WebCore::QualifiedName emptyValue() { return WebCore::nullQName(); }
    160     };
    161 }
    162 
    163 #endif
    164