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 "StaticConstructors.h" 30#include <wtf/Assertions.h> 31#include <wtf/HashSet.h> 32 33namespace WebCore { 34 35typedef HashSet<QualifiedName::QualifiedNameImpl*, QualifiedNameHash> QNameSet; 36 37struct QNameComponentsTranslator { 38 static unsigned hash(const QualifiedNameComponents& components) 39 { 40 return hashComponents(components); 41 } 42 static bool equal(QualifiedName::QualifiedNameImpl* name, const QualifiedNameComponents& c) 43 { 44 return c.m_prefix == name->m_prefix.impl() && c.m_localName == name->m_localName.impl() && c.m_namespace == name->m_namespace.impl(); 45 } 46 static void translate(QualifiedName::QualifiedNameImpl*& location, const QualifiedNameComponents& components, unsigned) 47 { 48 location = QualifiedName::QualifiedNameImpl::create(components.m_prefix, components.m_localName, components.m_namespace).releaseRef(); 49 } 50}; 51 52static QNameSet* gNameCache; 53 54void QualifiedName::init(const AtomicString& p, const AtomicString& l, const AtomicString& n) 55{ 56 if (!gNameCache) 57 gNameCache = new QNameSet; 58 QualifiedNameComponents components = { p.impl(), l.impl(), n.isEmpty() ? nullAtom.impl() : n.impl() }; 59 pair<QNameSet::iterator, bool> addResult = gNameCache->add<QualifiedNameComponents, QNameComponentsTranslator>(components); 60 m_impl = *addResult.first; 61 if (!addResult.second) 62 m_impl->ref(); 63} 64 65QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n) 66{ 67 init(p, l, n); 68} 69 70QualifiedName::QualifiedName(const AtomicString& p, const char* l, const AtomicString& n) 71{ 72 init(p, AtomicString(l), n); 73} 74 75void QualifiedName::deref() 76{ 77#ifdef QNAME_DEFAULT_CONSTRUCTOR 78 if (!m_impl) 79 return; 80#endif 81 82 if (m_impl->hasOneRef()) 83 gNameCache->remove(m_impl); 84 m_impl->deref(); 85} 86 87String QualifiedName::toString() const 88{ 89 String local = localName(); 90 if (hasPrefix()) 91 return prefix() + ":" + local; 92 return local; 93} 94 95// Global init routines 96DEFINE_GLOBAL(QualifiedName, anyName, nullAtom, starAtom, starAtom) 97 98void QualifiedName::init() 99{ 100 static bool initialized; 101 if (!initialized) { 102 // Use placement new to initialize the globals. 103 104 AtomicString::init(); 105 new ((void*)&anyName) QualifiedName(nullAtom, starAtom, starAtom); 106 initialized = true; 107 } 108} 109 110const AtomicString& QualifiedName::localNameUpper() const 111{ 112 if (!m_impl->m_localNameUpper) 113 m_impl->m_localNameUpper = m_impl->m_localName.upper(); 114 return m_impl->m_localNameUpper; 115} 116 117} 118