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