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 <wtf/Assertions.h> 30 #include <wtf/HashSet.h> 31 #include <wtf/StaticConstructors.h> 32 33 namespace WebCore { 34 35 typedef HashSet<QualifiedName::QualifiedNameImpl*, QualifiedNameHash> QNameSet; 36 37 struct 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 52 static QNameSet* gNameCache; 53 54 void 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 65 QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n) 66 { 67 init(p, l, n); 68 } 69 70 QualifiedName::QualifiedName(const AtomicString& p, const char* l, const AtomicString& n) 71 { 72 init(p, AtomicString(l), n); 73 } 74 75 QualifiedName::~QualifiedName() 76 { 77 deref(); 78 } 79 80 void QualifiedName::deref() 81 { 82 #ifdef QNAME_DEFAULT_CONSTRUCTOR 83 if (!m_impl) 84 return; 85 #endif 86 ASSERT(!isHashTableDeletedValue()); 87 88 if (m_impl->hasOneRef()) 89 gNameCache->remove(m_impl); 90 m_impl->deref(); 91 } 92 93 String QualifiedName::toString() const 94 { 95 String local = localName(); 96 if (hasPrefix()) { 97 String result = prefix().string(); 98 result.append(":"); 99 result.append(local); 100 return result; 101 } 102 return local; 103 } 104 105 // Global init routines 106 DEFINE_GLOBAL(QualifiedName, anyName, nullAtom, starAtom, starAtom) 107 108 void QualifiedName::init() 109 { 110 static bool initialized; 111 if (!initialized) { 112 // Use placement new to initialize the globals. 113 114 AtomicString::init(); 115 new ((void*)&anyName) QualifiedName(nullAtom, starAtom, starAtom); 116 initialized = true; 117 } 118 } 119 120 const AtomicString& QualifiedName::localNameUpper() const 121 { 122 if (!m_impl->m_localNameUpper) 123 m_impl->m_localNameUpper = m_impl->m_localName.upper(); 124 return m_impl->m_localNameUpper; 125 } 126 127 } 128