Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: webkit/pending/AtomicString.cpp

Issue 6500: Cleaning up the unfork (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/pending/AtomicString.h ('k') | webkit/pending/CSSStyleSelector.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 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
21 #include "config.h"
22
23 #ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
24 #define ATOMICSTRING_HIDE_GLOBALS 1
25 #endif
26
27 #include "AtomicString.h"
28
29 #include "StaticConstructors.h"
30 #include "StringHash.h"
31 #include <kjs/identifier.h>
32 #include <wtf/HashSet.h>
33
34 #if USE(JSC)
35 using KJS::Identifier;
36 using KJS::UString;
37 #endif
38
39 namespace WebCore {
40
41 static HashSet<StringImpl*>* stringTable;
42
43 struct CStringTranslator {
44 static unsigned hash(const char* c)
45 {
46 return StringImpl::computeHash(c);
47 }
48
49 static bool equal(StringImpl* r, const char* s)
50 {
51 int length = r->length();
52 const UChar* d = r->characters();
53 for (int i = 0; i != length; ++i) {
54 unsigned char c = s[i];
55 if (d[i] != c)
56 return false;
57 }
58 return s[length] == 0;
59 }
60
61 static void translate(StringImpl*& location, const char* const& c, unsigned hash)
62 {
63 location = new StringImpl(c, strlen(c), hash);
64 }
65 };
66
67 bool operator==(const AtomicString& a, const char* b)
68 {
69 StringImpl* impl = a.impl();
70 if ((!impl || !impl->characters()) && !b)
71 return true;
72 if ((!impl || !impl->characters()) || !b)
73 return false;
74 return CStringTranslator::equal(impl, b);
75 }
76
77 PassRefPtr<StringImpl> AtomicString::add(const char* c)
78 {
79 if (!c)
80 return 0;
81 if (!*c)
82 return StringImpl::empty();
83 pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable->add<cons t char*, CStringTranslator>(c);
84 if (!addResult.second)
85 return *addResult.first;
86 return adoptRef(*addResult.first);
87 }
88
89 struct UCharBuffer {
90 const UChar* s;
91 unsigned length;
92 };
93
94 static inline bool equal(StringImpl* string, const UChar* characters, unsigned l ength)
95 {
96 if (string->length() != length)
97 return false;
98
99 #if PLATFORM(ARM)
100 const UChar* stringCharacters = string->characters();
101 for (unsigned i = 0; i != length; ++i) {
102 if (*stringCharacters++ != *characters++)
103 return false;
104 }
105 return true;
106 #else
107 /* Do it 4-bytes-at-a-time on architectures where it's safe */
108
109 const uint32_t* stringCharacters = reinterpret_cast<const uint32_t*>(string- >characters());
110 const uint32_t* bufferCharacters = reinterpret_cast<const uint32_t*>(charact ers);
111
112 unsigned halfLength = length >> 1;
113 for (unsigned i = 0; i != halfLength; ++i) {
114 if (*stringCharacters++ != *bufferCharacters++)
115 return false;
116 }
117
118 if (length & 1 && *reinterpret_cast<const uint16_t*>(stringCharacters) != * reinterpret_cast<const uint16_t*>(bufferCharacters))
119 return false;
120
121 return true;
122 #endif
123 }
124
125 struct UCharBufferTranslator {
126 static unsigned hash(const UCharBuffer& buf)
127 {
128 return StringImpl::computeHash(buf.s, buf.length);
129 }
130
131 static bool equal(StringImpl* const& str, const UCharBuffer& buf)
132 {
133 return WebCore::equal(str, buf.s, buf.length);
134 }
135
136 static void translate(StringImpl*& location, const UCharBuffer& buf, unsigne d hash)
137 {
138 location = new StringImpl(buf.s, buf.length, hash);
139 }
140 };
141
142 struct HashAndCharacters {
143 unsigned hash;
144 const UChar* characters;
145 unsigned length;
146 };
147
148 struct HashAndCharactersTranslator {
149 static unsigned hash(const HashAndCharacters& buffer)
150 {
151 ASSERT(buffer.hash == StringImpl::computeHash(buffer.characters, buffer. length));
152 return buffer.hash;
153 }
154
155 static bool equal(StringImpl* const& string, const HashAndCharacters& buffer )
156 {
157 return WebCore::equal(string, buffer.characters, buffer.length);
158 }
159
160 static void translate(StringImpl*& location, const HashAndCharacters& buffer , unsigned hash)
161 {
162 location = new StringImpl(buffer.characters, buffer.length, hash);
163 }
164 };
165
166 PassRefPtr<StringImpl> AtomicString::add(const UChar* s, int length)
167 {
168 if (!s)
169 return 0;
170
171 if (length == 0)
172 return StringImpl::empty();
173
174 UCharBuffer buf = { s, length };
175 pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable->add<UCha rBuffer, UCharBufferTranslator>(buf);
176 if (!addResult.second)
177 return *addResult.first;
178 return adoptRef(*addResult.first);
179 }
180
181 PassRefPtr<StringImpl> AtomicString::add(const UChar* s)
182 {
183 if (!s)
184 return 0;
185
186 int length = 0;
187 while (s[length] != UChar(0))
188 length++;
189
190 if (length == 0)
191 return StringImpl::empty();
192
193 UCharBuffer buf = {s, length};
194 pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable->add<UCha rBuffer, UCharBufferTranslator>(buf);
195 if (!addResult.second)
196 return *addResult.first;
197 return adoptRef(*addResult.first);
198 }
199
200 PassRefPtr<StringImpl> AtomicString::add(StringImpl* r)
201 {
202 if (!r || r->m_inTable)
203 return r;
204
205 if (r->length() == 0)
206 return StringImpl::empty();
207
208 StringImpl* result = *stringTable->add(r).first;
209 if (result == r)
210 r->m_inTable = true;
211 return result;
212 }
213
214 void AtomicString::remove(StringImpl* r)
215 {
216 stringTable->remove(r);
217 }
218
219 #if USE(JSC)
220 PassRefPtr<StringImpl> AtomicString::add(const KJS::Identifier& identifier)
221 {
222 if (identifier.isNull())
223 return 0;
224
225 UString::Rep* string = identifier.ustring().rep();
226 unsigned length = string->size();
227 if (!length)
228 return StringImpl::empty();
229
230 HashAndCharacters buffer = { string->computedHash(), string->data(), length };
231 pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable->add<Hash AndCharacters, HashAndCharactersTranslator>(buffer);
232 if (!addResult.second)
233 return *addResult.first;
234 return adoptRef(*addResult.first);
235 }
236
237 PassRefPtr<StringImpl> AtomicString::add(const KJS::UString& ustring)
238 {
239 if (ustring.isNull())
240 return 0;
241
242 UString::Rep* string = ustring.rep();
243 unsigned length = string->size();
244 if (!length)
245 return StringImpl::empty();
246
247 HashAndCharacters buffer = { string->hash(), string->data(), length };
248 pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable->add<Hash AndCharacters, HashAndCharactersTranslator>(buffer);
249 if (!addResult.second)
250 return *addResult.first;
251 return adoptRef(*addResult.first);
252 }
253
254 AtomicStringImpl* AtomicString::find(const KJS::Identifier& identifier)
255 {
256 if (identifier.isNull())
257 return 0;
258
259 UString::Rep* string = identifier.ustring().rep();
260 unsigned length = string->size();
261 if (!length)
262 return static_cast<AtomicStringImpl*>(StringImpl::empty());
263
264 HashAndCharacters buffer = { string->computedHash(), string->data(), length };
265 HashSet<StringImpl*>::iterator iterator = stringTable->find<HashAndCharacter s, HashAndCharactersTranslator>(buffer);
266 if (iterator == stringTable->end())
267 return 0;
268 return static_cast<AtomicStringImpl*>(*iterator);
269 }
270
271 AtomicString::operator UString() const
272 {
273 return m_string;
274 }
275 #endif
276
277 DEFINE_GLOBAL(AtomicString, nullAtom)
278 DEFINE_GLOBAL(AtomicString, emptyAtom, "")
279 DEFINE_GLOBAL(AtomicString, textAtom, "#text")
280 DEFINE_GLOBAL(AtomicString, commentAtom, "#comment")
281 DEFINE_GLOBAL(AtomicString, starAtom, "*")
282
283 void AtomicString::init()
284 {
285 static bool initialized;
286 if (!initialized) {
287 stringTable = new HashSet<StringImpl*>;
288
289 // Use placement new to initialize the globals.
290 new ((void*)&nullAtom) AtomicString;
291 new ((void*)&emptyAtom) AtomicString("");
292 new ((void*)&textAtom) AtomicString("#text");
293 new ((void*)&commentAtom) AtomicString("#comment");
294 new ((void*)&starAtom) AtomicString("*");
295
296 initialized = true;
297 }
298 }
299
300 }
OLDNEW
« no previous file with comments | « webkit/pending/AtomicString.h ('k') | webkit/pending/CSSStyleSelector.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698