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