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