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 #include "config.h"
     21 
     22 #ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
     23 #define WEBCORE_QUALIFIEDNAME_HIDE_GLOBALS 1
     24 #else
     25 #define QNAME_DEFAULT_CONSTRUCTOR
     26 #endif
     27 
     28 #include "HTMLNames.h"
     29 #include "SVGNames.h"
     30 #include "XLinkNames.h"
     31 #include "XMLNSNames.h"
     32 #include "XMLNames.h"
     33 #include "core/dom/QualifiedName.h"
     34 #include "wtf/Assertions.h"
     35 #include "wtf/HashSet.h"
     36 #include "wtf/StaticConstructors.h"
     37 
     38 namespace WebCore {
     39 
     40 static const int staticQualifiedNamesCount = HTMLNames::HTMLTagsCount + HTMLNames::HTMLAttrsCount
     41     + SVGNames::SVGTagsCount + SVGNames::SVGAttrsCount
     42     + XLinkNames::XLinkAttrsCount
     43     + XMLNSNames::XMLNSAttrsCount
     44     + XMLNames::XMLAttrsCount;
     45 
     46 struct QualifiedNameHashTraits : public HashTraits<QualifiedName::QualifiedNameImpl*> {
     47     static const int minimumTableSize = WTF::HashTableCapacityForSize<staticQualifiedNamesCount>::value;
     48 };
     49 
     50 typedef HashSet<QualifiedName::QualifiedNameImpl*, QualifiedNameHash, QualifiedNameHashTraits> QNameSet;
     51 
     52 struct QNameComponentsTranslator {
     53     static unsigned hash(const QualifiedNameComponents& components)
     54     {
     55         return hashComponents(components);
     56     }
     57     static bool equal(QualifiedName::QualifiedNameImpl* name, const QualifiedNameComponents& c)
     58     {
     59         return c.m_prefix == name->m_prefix.impl() && c.m_localName == name->m_localName.impl() && c.m_namespace == name->m_namespace.impl();
     60     }
     61     static void translate(QualifiedName::QualifiedNameImpl*& location, const QualifiedNameComponents& components, unsigned)
     62     {
     63         location = QualifiedName::QualifiedNameImpl::create(components.m_prefix, components.m_localName, components.m_namespace).leakRef();
     64     }
     65 };
     66 
     67 static QNameSet* gNameCache;
     68 
     69 QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
     70 {
     71     if (!gNameCache)
     72         gNameCache = new QNameSet;
     73     QualifiedNameComponents components = { p.impl(), l.impl(), n.isEmpty() ? nullAtom.impl() : n.impl() };
     74     QNameSet::AddResult addResult = gNameCache->add<QNameComponentsTranslator>(components);
     75     m_impl = *addResult.iterator;
     76     if (!addResult.isNewEntry)
     77         m_impl->ref();
     78 }
     79 
     80 QualifiedName::~QualifiedName()
     81 {
     82     deref();
     83 }
     84 
     85 void QualifiedName::deref()
     86 {
     87 #ifdef QNAME_DEFAULT_CONSTRUCTOR
     88     if (!m_impl)
     89         return;
     90 #endif
     91     ASSERT(!isHashTableDeletedValue());
     92     m_impl->deref();
     93 }
     94 
     95 QualifiedName::QualifiedNameImpl::~QualifiedNameImpl()
     96 {
     97     gNameCache->remove(this);
     98 }
     99 
    100 String QualifiedName::toString() const
    101 {
    102     String local = localName();
    103     if (hasPrefix())
    104         return prefix().string() + ":" + local;
    105     return local;
    106 }
    107 
    108 // Global init routines
    109 DEFINE_GLOBAL(QualifiedName, anyName, nullAtom, starAtom, starAtom)
    110 
    111 void QualifiedName::init()
    112 {
    113     ASSERT(starAtom.impl());
    114     new ((void*)&anyName) QualifiedName(nullAtom, starAtom, starAtom);
    115 }
    116 
    117 const QualifiedName& nullQName()
    118 {
    119     DEFINE_STATIC_LOCAL(QualifiedName, nullName, (nullAtom, nullAtom, nullAtom));
    120     return nullName;
    121 }
    122 
    123 const AtomicString& QualifiedName::localNameUpper() const
    124 {
    125     if (!m_impl->m_localNameUpper)
    126         m_impl->m_localNameUpper = m_impl->m_localName.upper();
    127     return m_impl->m_localNameUpper;
    128 }
    129 
    130 unsigned QualifiedName::QualifiedNameImpl::computeHash() const
    131 {
    132     QualifiedNameComponents components = { m_prefix.impl(), m_localName.impl(), m_namespace.impl() };
    133     return hashComponents(components);
    134 }
    135 
    136 void createQualifiedName(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace)
    137 {
    138     new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nameNamespace);
    139 }
    140 
    141 void createQualifiedName(void* targetAddress, StringImpl* name)
    142 {
    143     new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nullAtom);
    144 }
    145 
    146 }
    147