fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / khtml / misc / idstring.cpp
blob79e3cf87734e879533eba57aec017b347465bda8
1 /*
2 * This file is part of the DOM implementation for KDE.
4 * Copyright (C) 2008 Maksim Orlovich (maksim@kde.org)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 #include "idstring.h"
24 #include <assert.h>
26 namespace khtml {
28 CaseNormalizeMode IDTableBase::MappingKey::caseNormalizationMode;
30 bool IDTableBase::MappingKey::operator==(const MappingKey& other) const
32 if (IDTableBase::MappingKey::caseNormalizationMode == IDS_CaseSensitive)
33 return str == other.str;
34 else
35 return !strcasecmp(str, other.str);
38 static inline unsigned int qHash(const IDTableBase::MappingKey& key) {
39 if (key.str.isNull() || key.caseNormalizationMode == IDS_CaseSensitive) {
40 return qHash(key.str);
41 } else if (key.caseNormalizationMode == IDS_NormalizeLower) {
42 return key.str.implementation()->lowerHash();
43 } else { // caseNormalizationMode == IDS_NormalizeUpper
44 return key.str.implementation()->upperHash();
48 void IDTableBase::releaseId(unsigned id)
50 IDTableBase::MappingKey::caseNormalizationMode = IDS_CaseSensitive;
52 m_mappingLookup.remove(m_mappings[id].name);
53 m_idFreeList.append(id);
56 unsigned short IDTableBase::grabId(const DOMString& origName, CaseNormalizeMode cnm)
58 unsigned short newId;
60 // Check for existing one, ignoring case if needed
61 IDTableBase::MappingKey::caseNormalizationMode = cnm;
62 QHash<MappingKey, unsigned short>::const_iterator i = m_mappingLookup.constFind(origName);
63 if (i != m_mappingLookup.constEnd()) {
64 newId = *i;
65 refId(newId);
66 return newId;
69 // Nope. Allocate new ID. If there is normalization going on, we may now have to
70 // update our case so the canonical mapping is of the expected case.
71 DOMString name;
72 switch (cnm) {
73 case IDS_CaseSensitive:
74 name = origName;
75 break;
76 case IDS_NormalizeUpper:
77 name = origName.upper();
78 break;
79 case IDS_NormalizeLower:
80 name = origName.lower();
81 break;
84 if (!m_idFreeList.isEmpty()) {
85 // Grab from freelist..
86 newId = m_idFreeList.last();
87 m_idFreeList.removeLast();
88 m_mappings[newId].name = name;
89 } else {
90 // Make a new one --- if we can (we keep one spot for "last resort" mapping)
91 if (m_mappings.size() < 0xFFFE) {
92 m_mappings.append(Mapping(name));
93 newId = m_mappings.size() - 1;
94 } else {
95 // We ran out of resources. Did we add a fallback mapping yet?
96 if (m_mappings.size() == 0xFFFE) {
97 // Have an ID for "everything else" as last resource. This sucks
98 m_mappings.append(Mapping("_khtml_fallback"));
99 m_mappings[0xFFFF].refCount = 1; // pin it.
101 newId = 0xFFFF;
105 m_mappingLookup[name] = newId;
107 refId(newId);
108 return newId;
111 void IDTableBase::addStaticMapping(unsigned id, const DOMString& name)
113 IDTableBase::MappingKey::caseNormalizationMode = IDS_CaseSensitive;
115 assert(id == m_mappings.size());
116 assert(!m_mappingLookup.contains(name));
117 m_mappings.append(Mapping(name));
118 m_mappings[m_mappings.size() - 1].refCount = 1; // Pin it.
119 m_mappingLookup[name] = id;
122 void IDTableBase::addHiddenMapping(unsigned id, const DOMString& name)
124 assert(id == m_mappings.size());
125 m_mappings.append(Mapping(name));
126 m_mappings[m_mappings.size() - 1].refCount = 1; // Pin it.
131 // kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;