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 #include "core/dom/QualifiedName.h"
     23 
     24 #include "core/HTMLNames.h"
     25 #include "core/MathMLNames.h"
     26 #include "core/SVGNames.h"
     27 #include "core/XLinkNames.h"
     28 #include "core/XMLNSNames.h"
     29 #include "core/XMLNames.h"
     30 #include "wtf/Assertions.h"
     31 #include "wtf/HashSet.h"
     32 #include "wtf/MainThread.h"
     33 #include "wtf/StaticConstructors.h"
     34 
     35 namespace blink {
     36 
     37 struct SameSizeAsQualifiedNameImpl : public RefCounted<SameSizeAsQualifiedNameImpl> {
     38     unsigned bitfield;
     39     void* pointers[4];
     40 };
     41 
     42 COMPILE_ASSERT(sizeof(QualifiedName::QualifiedNameImpl) == sizeof(SameSizeAsQualifiedNameImpl), qualified_name_impl_should_stay_small);
     43 
     44 static const int staticQualifiedNamesCount = HTMLNames::HTMLTagsCount + HTMLNames::HTMLAttrsCount
     45     + MathMLNames::MathMLTagsCount + MathMLNames::MathMLAttrsCount
     46     + SVGNames::SVGTagsCount + SVGNames::SVGAttrsCount
     47     + XLinkNames::XLinkAttrsCount
     48     + XMLNSNames::XMLNSAttrsCount
     49     + XMLNames::XMLAttrsCount;
     50 
     51 struct QualifiedNameHashTraits : public HashTraits<QualifiedName::QualifiedNameImpl*> {
     52     static const unsigned minimumTableSize = WTF::HashTableCapacityForSize<staticQualifiedNamesCount>::value;
     53 };
     54 
     55 typedef HashSet<QualifiedName::QualifiedNameImpl*, QualifiedNameHash, QualifiedNameHashTraits> QualifiedNameCache;
     56 
     57 static QualifiedNameCache& qualifiedNameCache()
     58 {
     59     // This code is lockless and thus assumes it all runs on one thread!
     60     ASSERT(isMainThread());
     61     static QualifiedNameCache* gNameCache = new QualifiedNameCache;
     62     return *gNameCache;
     63 }
     64 
     65 struct QNameComponentsTranslator {
     66     static unsigned hash(const QualifiedNameData& data)
     67     {
     68         return hashComponents(data.m_components);
     69     }
     70     static bool equal(QualifiedName::QualifiedNameImpl* name, const QualifiedNameData& data)
     71     {
     72         return data.m_components.m_prefix == name->m_prefix.impl()
     73             && data.m_components.m_localName == name->m_localName.impl()
     74             && data.m_components.m_namespace == name->m_namespace.impl();
     75     }
     76     static void translate(QualifiedName::QualifiedNameImpl*& location, const QualifiedNameData& data, unsigned)
     77     {
     78         const QualifiedNameComponents& components = data.m_components;
     79         location = QualifiedName::QualifiedNameImpl::create(AtomicString(components.m_prefix), AtomicString(components.m_localName), AtomicString(components.m_namespace), data.m_isStatic).leakRef();
     80     }
     81 };
     82 
     83 QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
     84 {
     85     QualifiedNameData data = { { p.impl(), l.impl(), n.isEmpty() ? nullAtom.impl() : n.impl() }, false };
     86     QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(data);
     87     m_impl = addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult.storedValue;
     88 }
     89 
     90 QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n, bool isStatic)
     91 {
     92     QualifiedNameData data = { { p.impl(), l.impl(), n.impl() }, isStatic };
     93     QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(data);
     94     m_impl = addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult.storedValue;
     95 }
     96 
     97 QualifiedName::~QualifiedName()
     98 {
     99 }
    100 
    101 QualifiedName::QualifiedNameImpl::~QualifiedNameImpl()
    102 {
    103     qualifiedNameCache().remove(this);
    104 }
    105 
    106 String QualifiedName::toString() const
    107 {
    108     String local = localName();
    109     if (hasPrefix())
    110         return prefix().string() + ":" + local;
    111     return local;
    112 }
    113 
    114 // Global init routines
    115 DEFINE_GLOBAL(QualifiedName, anyName, nullAtom, starAtom, starAtom)
    116 
    117 void QualifiedName::init()
    118 {
    119     ASSERT(starAtom.impl());
    120     new ((void*)&anyName) QualifiedName(nullAtom, starAtom, starAtom, true );
    121 }
    122 
    123 const QualifiedName& QualifiedName::null()
    124 {
    125     DEFINE_STATIC_LOCAL(QualifiedName, nullName, (nullAtom, nullAtom, nullAtom, true));
    126     return nullName;
    127 }
    128 
    129 const AtomicString& QualifiedName::localNameUpper() const
    130 {
    131     if (!m_impl->m_localNameUpper)
    132         m_impl->m_localNameUpper = m_impl->m_localName.upper();
    133     return m_impl->m_localNameUpper;
    134 }
    135 
    136 unsigned QualifiedName::QualifiedNameImpl::computeHash() const
    137 {
    138     QualifiedNameComponents components = { m_prefix.impl(), m_localName.impl(), m_namespace.impl() };
    139     return hashComponents(components);
    140 }
    141 
    142 void QualifiedName::createStatic(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace)
    143 {
    144     new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nameNamespace, true);
    145 }
    146 
    147 void QualifiedName::createStatic(void* targetAddress, StringImpl* name)
    148 {
    149     new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nullAtom, true);
    150 }
    151 
    152 }
    153