18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2005, 2006, 2009 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef QualifiedName_h
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define QualifiedName_h
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/HashTraits.h>
25f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <wtf/text/AtomicString.h>
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstruct QualifiedNameComponents {
30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    StringImpl* m_prefix;
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    StringImpl* m_localName;
32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    StringImpl* m_namespace;
33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project};
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass QualifiedName {
36ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_FAST_ALLOCATED;
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> {
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public:
408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI));
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
45cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        const AtomicString m_prefix;
46cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        const AtomicString m_localName;
47cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        const AtomicString m_namespace;
48cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        mutable AtomicString m_localNameUpper;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private:
518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            : m_prefix(prefix)
538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            , m_localName(localName)
545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            , m_namespace(namespaceURI)
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ASSERT(!namespaceURI.isEmpty() || namespaceURI.isNull());
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    QualifiedName(const AtomicString& prefix, const char* localName, const AtomicString& namespaceURI);
6221939df44de1705786c545cd1bf519d47250322dBen Murdoch    QualifiedName(WTF::HashTableDeletedValueType) : m_impl(hashTableDeletedValue()) { }
6321939df44de1705786c545cd1bf519d47250322dBen Murdoch    bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); }
64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ~QualifiedName();
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef QNAME_DEFAULT_CONSTRUCTOR
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QualifiedName() : m_impl(0) { }
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { ref(); }
708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    const QualifiedName& operator=(const QualifiedName& other) { other.ref(); deref(); m_impl = other.m_impl; return *this; }
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool operator==(const QualifiedName& other) const { return m_impl == other.m_impl; }
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool operator!=(const QualifiedName& other) const { return !(*this == other); }
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool matches(const QualifiedName& other) const { return m_impl == other.m_impl || (localName() == other.localName() && namespaceURI() == other.namespaceURI()); }
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hasPrefix() const { return m_impl->m_prefix != nullAtom; }
788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    void setPrefix(const AtomicString& prefix) { *this = QualifiedName(prefix, localName(), namespaceURI()); }
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& prefix() const { return m_impl->m_prefix; }
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& localName() const { return m_impl->m_localName; }
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& namespaceURI() const { return m_impl->m_namespace; }
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
84cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // Uppercased localName, cached for efficiency
85cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    const AtomicString& localNameUpper() const;
86cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String toString() const;
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QualifiedNameImpl* impl() const { return m_impl; }
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Init routine for globals
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static void init();
93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprivate:
95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    void init(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    void ref() const { m_impl->ref(); }
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void deref();
9821939df44de1705786c545cd1bf519d47250322dBen Murdoch
9921939df44de1705786c545cd1bf519d47250322dBen Murdoch    static QualifiedNameImpl* hashTableDeletedValue() { return RefPtr<QualifiedNameImpl>::hashTableDeletedValue(); }
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QualifiedNameImpl* m_impl;
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef WEBCORE_QUALIFIEDNAME_HIDE_GLOBALS
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectextern const QualifiedName anyName;
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline const QualifiedName& anyQName() { return anyName; }
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline bool operator==(const AtomicString& a, const QualifiedName& q) { return a == q.localName(); }
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a != q.localName(); }
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); }
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline bool operator!=(const QualifiedName& q, const AtomicString& a) { return a != q.localName(); }
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectinline unsigned hashComponents(const QualifiedNameComponents& buf)
115635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
1162bde8e466a4451c7319e3a072d118917957d6554Steve Block    return StringHasher::hashMemory<sizeof(QualifiedNameComponents)>(&buf);
117635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
118bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstruct QualifiedNameHash {
120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    static unsigned hash(const QualifiedName& name) { return hash(name.impl()); }
121bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    static unsigned hash(const QualifiedName::QualifiedNameImpl* name)
123bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    {
124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        QualifiedNameComponents c = { name->m_prefix.impl(), name->m_localName.impl(), name->m_namespace.impl() };
125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return hashComponents(c);
126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
127bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    static bool equal(const QualifiedName& a, const QualifiedName& b) { return a == b; }
129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    static bool equal(const QualifiedName::QualifiedNameImpl* a, const QualifiedName::QualifiedNameImpl* b) { return a == b; }
130bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    static const bool safeToCompareToEmptyOrDeleted = false;
132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project};
133bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace WTF {
137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    template<typename T> struct DefaultHash;
1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
140635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    template<> struct DefaultHash<WebCore::QualifiedName> {
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        typedef WebCore::QualifiedNameHash Hash;
142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    };
143635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    template<> struct HashTraits<WebCore::QualifiedName> : SimpleClassHashTraits<WebCore::QualifiedName> {
145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        static const bool emptyValueIsZero = false;
146dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        static WebCore::QualifiedName emptyValue() { return WebCore::QualifiedName(nullAtom, nullAtom, nullAtom); }
147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    };
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
151