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

Side by Side Diff: third_party/WebKit/Source/wtf/text/AtomicString.cpp

Issue 1436153002: Apply clang-format with Chromium-style without column limit. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> 3 * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
4 * Copyright (C) 2012 Google Inc. All rights reserved. 4 * Copyright (C) 2012 Google Inc. All rights reserved.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 19 matching lines...) Expand all
30 #include "wtf/text/IntegerToStringConversion.h" 30 #include "wtf/text/IntegerToStringConversion.h"
31 #include "wtf/text/UTF8.h" 31 #include "wtf/text/UTF8.h"
32 32
33 namespace WTF { 33 namespace WTF {
34 34
35 using namespace Unicode; 35 using namespace Unicode;
36 36
37 static_assert(sizeof(AtomicString) == sizeof(String), "AtomicString and String m ust be same size"); 37 static_assert(sizeof(AtomicString) == sizeof(String), "AtomicString and String m ust be same size");
38 38
39 class AtomicStringTable { 39 class AtomicStringTable {
40 WTF_MAKE_NONCOPYABLE(AtomicStringTable); 40 WTF_MAKE_NONCOPYABLE(AtomicStringTable);
41 public: 41
42 static AtomicStringTable* create(WTFThreadData& data) 42 public:
43 { 43 static AtomicStringTable* create(WTFThreadData& data) {
44 data.m_atomicStringTable = new AtomicStringTable; 44 data.m_atomicStringTable = new AtomicStringTable;
45 data.m_atomicStringTableDestructor = AtomicStringTable::destroy; 45 data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
46 data.m_atomicStringTable->addStaticStrings(); 46 data.m_atomicStringTable->addStaticStrings();
47 return data.m_atomicStringTable; 47 return data.m_atomicStringTable;
48 }
49
50 StringImpl* addStringImpl(StringImpl* string) {
51 if (!string->length())
52 return StringImpl::empty();
53
54 StringImpl* result = *m_table.add(string).storedValue;
55
56 if (!result->isAtomic())
57 result->setIsAtomic(true);
58
59 ASSERT(!string->isStatic() || result->isStatic());
60 return result;
61 }
62
63 HashSet<StringImpl*>& table() {
64 return m_table;
65 }
66
67 private:
68 AtomicStringTable() {}
69
70 void addStaticStrings() {
71 const StaticStringsTable& staticStrings = StringImpl::allStaticStrings();
72
73 StaticStringsTable::const_iterator it = staticStrings.begin();
74 for (; it != staticStrings.end(); ++it) {
75 addStringImpl(it->value);
48 } 76 }
49 77 }
50 StringImpl* addStringImpl(StringImpl* string) 78
51 { 79 static void destroy(AtomicStringTable* table) {
52 if (!string->length()) 80 HashSet<StringImpl*>::iterator end = table->m_table.end();
53 return StringImpl::empty(); 81 for (HashSet<StringImpl*>::iterator iter = table->m_table.begin(); iter != e nd; ++iter) {
54 82 StringImpl* string = *iter;
55 StringImpl* result = *m_table.add(string).storedValue; 83 if (!string->isStatic()) {
56 84 ASSERT(string->isAtomic());
57 if (!result->isAtomic()) 85 string->setIsAtomic(false);
58 result->setIsAtomic(true); 86 }
59
60 ASSERT(!string->isStatic() || result->isStatic());
61 return result;
62 } 87 }
63 88 delete table;
64 HashSet<StringImpl*>& table() 89 }
65 { 90
66 return m_table; 91 HashSet<StringImpl*> m_table;
67 } 92 };
68 93
69 private: 94 static inline AtomicStringTable& atomicStringTable() {
70 AtomicStringTable() { } 95 // Once possible we should make this non-lazy (constructed in WTFThreadData's constructor).
71 96 WTFThreadData& data = wtfThreadData();
72 void addStaticStrings() 97 AtomicStringTable* table = data.atomicStringTable();
73 { 98 if (UNLIKELY(!table))
74 const StaticStringsTable& staticStrings = StringImpl::allStaticStrings() ; 99 table = AtomicStringTable::create(data);
75 100 return *table;
76 StaticStringsTable::const_iterator it = staticStrings.begin(); 101 }
77 for (; it != staticStrings.end(); ++it) { 102
78 addStringImpl(it->value); 103 static inline HashSet<StringImpl*>& atomicStrings() {
79 } 104 return atomicStringTable().table();
80 } 105 }
81 106
82 static void destroy(AtomicStringTable* table) 107 void AtomicString::reserveTableCapacity(size_t size) {
83 { 108 atomicStringTable().table().reserveCapacityForSize(size);
84 HashSet<StringImpl*>::iterator end = table->m_table.end(); 109 }
85 for (HashSet<StringImpl*>::iterator iter = table->m_table.begin(); iter != end; ++iter) { 110
86 StringImpl* string = *iter; 111 template <typename T, typename HashTranslator>
87 if (!string->isStatic()) { 112 static inline PassRefPtr<StringImpl> addToStringTable(const T& value) {
88 ASSERT(string->isAtomic()); 113 HashSet<StringImpl*>::AddResult addResult = atomicStrings().add<HashTranslator >(value);
89 string->setIsAtomic(false); 114
90 } 115 // If the string is newly-translated, then we need to adopt it.
91 } 116 // The boolean in the pair tells us if that is so.
92 delete table; 117 return addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult.st oredValue;
93 } 118 }
94 119
95 HashSet<StringImpl*> m_table; 120 PassRefPtr<StringImpl> AtomicString::add(const LChar* c) {
96 }; 121 if (!c)
97 122 return nullptr;
98 static inline AtomicStringTable& atomicStringTable() 123 if (!*c)
99 { 124 return StringImpl::empty();
100 // Once possible we should make this non-lazy (constructed in WTFThreadData' s constructor). 125
101 WTFThreadData& data = wtfThreadData(); 126 return add(c, strlen(reinterpret_cast<const char*>(c)));
102 AtomicStringTable* table = data.atomicStringTable(); 127 }
103 if (UNLIKELY(!table)) 128
104 table = AtomicStringTable::create(data); 129 template <typename CharacterType>
105 return *table;
106 }
107
108 static inline HashSet<StringImpl*>& atomicStrings()
109 {
110 return atomicStringTable().table();
111 }
112
113 void AtomicString::reserveTableCapacity(size_t size)
114 {
115 atomicStringTable().table().reserveCapacityForSize(size);
116 }
117
118 template<typename T, typename HashTranslator>
119 static inline PassRefPtr<StringImpl> addToStringTable(const T& value)
120 {
121 HashSet<StringImpl*>::AddResult addResult = atomicStrings().add<HashTranslat or>(value);
122
123 // If the string is newly-translated, then we need to adopt it.
124 // The boolean in the pair tells us if that is so.
125 return addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult. storedValue;
126 }
127
128 PassRefPtr<StringImpl> AtomicString::add(const LChar* c)
129 {
130 if (!c)
131 return nullptr;
132 if (!*c)
133 return StringImpl::empty();
134
135 return add(c, strlen(reinterpret_cast<const char*>(c)));
136 }
137
138 template<typename CharacterType>
139 struct HashTranslatorCharBuffer { 130 struct HashTranslatorCharBuffer {
140 const CharacterType* s; 131 const CharacterType* s;
141 unsigned length; 132 unsigned length;
142 }; 133 };
143 134
144 typedef HashTranslatorCharBuffer<UChar> UCharBuffer; 135 typedef HashTranslatorCharBuffer<UChar> UCharBuffer;
145 struct UCharBufferTranslator { 136 struct UCharBufferTranslator {
146 static unsigned hash(const UCharBuffer& buf) 137 static unsigned hash(const UCharBuffer& buf) {
147 { 138 return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length);
148 return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length); 139 }
140
141 static bool equal(StringImpl* const& str, const UCharBuffer& buf) {
142 return WTF::equal(str, buf.s, buf.length);
143 }
144
145 static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash) {
146 location = StringImpl::create8BitIfPossible(buf.s, buf.length).leakRef();
147 location->setHash(hash);
148 location->setIsAtomic(true);
149 }
150 };
151
152 template <typename CharacterType>
153 struct HashAndCharacters {
154 unsigned hash;
155 const CharacterType* characters;
156 unsigned length;
157 };
158
159 template <typename CharacterType>
160 struct HashAndCharactersTranslator {
161 static unsigned hash(const HashAndCharacters<CharacterType>& buffer) {
162 ASSERT(buffer.hash == StringHasher::computeHashAndMaskTop8Bits(buffer.charac ters, buffer.length));
163 return buffer.hash;
164 }
165
166 static bool equal(StringImpl* const& string, const HashAndCharacters<Character Type>& buffer) {
167 return WTF::equal(string, buffer.characters, buffer.length);
168 }
169
170 static void translate(StringImpl*& location, const HashAndCharacters<Character Type>& buffer, unsigned hash) {
171 location = StringImpl::create(buffer.characters, buffer.length).leakRef();
172 location->setHash(hash);
173 location->setIsAtomic(true);
174 }
175 };
176
177 struct HashAndUTF8Characters {
178 unsigned hash;
179 const char* characters;
180 unsigned length;
181 unsigned utf16Length;
182 };
183
184 struct HashAndUTF8CharactersTranslator {
185 static unsigned hash(const HashAndUTF8Characters& buffer) {
186 return buffer.hash;
187 }
188
189 static bool equal(StringImpl* const& string, const HashAndUTF8Characters& buff er) {
190 if (buffer.utf16Length != string->length())
191 return false;
192
193 // If buffer contains only ASCII characters UTF-8 and UTF16 length are the s ame.
194 if (buffer.utf16Length != buffer.length) {
195 if (string->is8Bit()) {
196 const LChar* characters8 = string->characters8();
197 return equalLatin1WithUTF8(characters8, characters8 + string->length(), buffer.characters, buffer.characters + buffer.length);
198 }
199 const UChar* characters16 = string->characters16();
200 return equalUTF16WithUTF8(characters16, characters16 + string->length(), b uffer.characters, buffer.characters + buffer.length);
149 } 201 }
150 202
151 static bool equal(StringImpl* const& str, const UCharBuffer& buf) 203 if (string->is8Bit()) {
152 { 204 const LChar* stringCharacters = string->characters8();
153 return WTF::equal(str, buf.s, buf.length); 205
206 for (unsigned i = 0; i < buffer.length; ++i) {
207 ASSERT(isASCII(buffer.characters[i]));
208 if (stringCharacters[i] != buffer.characters[i])
209 return false;
210 }
211
212 return true;
154 } 213 }
155 214
156 static void translate(StringImpl*& location, const UCharBuffer& buf, unsigne d hash) 215 const UChar* stringCharacters = string->characters16();
157 { 216
158 location = StringImpl::create8BitIfPossible(buf.s, buf.length).leakRef() ; 217 for (unsigned i = 0; i < buffer.length; ++i) {
159 location->setHash(hash); 218 ASSERT(isASCII(buffer.characters[i]));
160 location->setIsAtomic(true); 219 if (stringCharacters[i] != buffer.characters[i])
220 return false;
161 } 221 }
162 }; 222
163 223 return true;
164 template<typename CharacterType> 224 }
165 struct HashAndCharacters { 225
166 unsigned hash; 226 static void translate(StringImpl*& location, const HashAndUTF8Characters& buff er, unsigned hash) {
167 const CharacterType* characters; 227 UChar* target;
168 unsigned length; 228 RefPtr<StringImpl> newString = StringImpl::createUninitialized(buffer.utf16L ength, target);
169 }; 229
170 230 bool isAllASCII;
171 template<typename CharacterType> 231 const char* source = buffer.characters;
172 struct HashAndCharactersTranslator { 232 if (convertUTF8ToUTF16(&source, source + buffer.length, &target, target + bu ffer.utf16Length, &isAllASCII) != conversionOK)
173 static unsigned hash(const HashAndCharacters<CharacterType>& buffer) 233 ASSERT_NOT_REACHED();
174 { 234
175 ASSERT(buffer.hash == StringHasher::computeHashAndMaskTop8Bits(buffer.ch aracters, buffer.length)); 235 if (isAllASCII)
176 return buffer.hash; 236 newString = StringImpl::create(buffer.characters, buffer.length);
177 } 237
178 238 location = newString.release().leakRef();
179 static bool equal(StringImpl* const& string, const HashAndCharacters<Charact erType>& buffer) 239 location->setHash(hash);
180 { 240 location->setIsAtomic(true);
181 return WTF::equal(string, buffer.characters, buffer.length); 241 }
182 } 242 };
183 243
184 static void translate(StringImpl*& location, const HashAndCharacters<Charact erType>& buffer, unsigned hash) 244 PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length) {
185 { 245 if (!s)
186 location = StringImpl::create(buffer.characters, buffer.length).leakRef( ); 246 return nullptr;
187 location->setHash(hash); 247
188 location->setIsAtomic(true); 248 if (!length)
189 } 249 return StringImpl::empty();
190 }; 250
191 251 UCharBuffer buffer = {s, length};
192 struct HashAndUTF8Characters { 252 return addToStringTable<UCharBuffer, UCharBufferTranslator>(buffer);
193 unsigned hash; 253 }
194 const char* characters; 254
195 unsigned length; 255 PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length, unsign ed existingHash) {
196 unsigned utf16Length; 256 ASSERT(s);
197 }; 257 ASSERT(existingHash);
198 258
199 struct HashAndUTF8CharactersTranslator { 259 if (!length)
200 static unsigned hash(const HashAndUTF8Characters& buffer) 260 return StringImpl::empty();
201 { 261
202 return buffer.hash; 262 HashAndCharacters<UChar> buffer = {existingHash, s, length};
203 } 263 return addToStringTable<HashAndCharacters<UChar>, HashAndCharactersTranslator< UChar>>(buffer);
204 264 }
205 static bool equal(StringImpl* const& string, const HashAndUTF8Characters& bu ffer) 265
206 { 266 PassRefPtr<StringImpl> AtomicString::add(const UChar* s) {
207 if (buffer.utf16Length != string->length()) 267 if (!s)
208 return false; 268 return nullptr;
209 269
210 // If buffer contains only ASCII characters UTF-8 and UTF16 length are t he same. 270 unsigned length = 0;
211 if (buffer.utf16Length != buffer.length) { 271 while (s[length] != UChar(0))
212 if (string->is8Bit()) { 272 ++length;
213 const LChar* characters8 = string->characters8(); 273
214 return equalLatin1WithUTF8(characters8, characters8 + string->le ngth(), buffer.characters, buffer.characters + buffer.length); 274 if (!length)
215 } 275 return StringImpl::empty();
216 const UChar* characters16 = string->characters16(); 276
217 return equalUTF16WithUTF8(characters16, characters16 + string->lengt h(), buffer.characters, buffer.characters + buffer.length); 277 UCharBuffer buffer = {s, length};
218 } 278 return addToStringTable<UCharBuffer, UCharBufferTranslator>(buffer);
219
220 if (string->is8Bit()) {
221 const LChar* stringCharacters = string->characters8();
222
223 for (unsigned i = 0; i < buffer.length; ++i) {
224 ASSERT(isASCII(buffer.characters[i]));
225 if (stringCharacters[i] != buffer.characters[i])
226 return false;
227 }
228
229 return true;
230 }
231
232 const UChar* stringCharacters = string->characters16();
233
234 for (unsigned i = 0; i < buffer.length; ++i) {
235 ASSERT(isASCII(buffer.characters[i]));
236 if (stringCharacters[i] != buffer.characters[i])
237 return false;
238 }
239
240 return true;
241 }
242
243 static void translate(StringImpl*& location, const HashAndUTF8Characters& bu ffer, unsigned hash)
244 {
245 UChar* target;
246 RefPtr<StringImpl> newString = StringImpl::createUninitialized(buffer.ut f16Length, target);
247
248 bool isAllASCII;
249 const char* source = buffer.characters;
250 if (convertUTF8ToUTF16(&source, source + buffer.length, &target, target + buffer.utf16Length, &isAllASCII) != conversionOK)
251 ASSERT_NOT_REACHED();
252
253 if (isAllASCII)
254 newString = StringImpl::create(buffer.characters, buffer.length);
255
256 location = newString.release().leakRef();
257 location->setHash(hash);
258 location->setIsAtomic(true);
259 }
260 };
261
262 PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length)
263 {
264 if (!s)
265 return nullptr;
266
267 if (!length)
268 return StringImpl::empty();
269
270 UCharBuffer buffer = { s, length };
271 return addToStringTable<UCharBuffer, UCharBufferTranslator>(buffer);
272 }
273
274 PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length, unsign ed existingHash)
275 {
276 ASSERT(s);
277 ASSERT(existingHash);
278
279 if (!length)
280 return StringImpl::empty();
281
282 HashAndCharacters<UChar> buffer = { existingHash, s, length };
283 return addToStringTable<HashAndCharacters<UChar>, HashAndCharactersTranslato r<UChar>>(buffer);
284 }
285
286 PassRefPtr<StringImpl> AtomicString::add(const UChar* s)
287 {
288 if (!s)
289 return nullptr;
290
291 unsigned length = 0;
292 while (s[length] != UChar(0))
293 ++length;
294
295 if (!length)
296 return StringImpl::empty();
297
298 UCharBuffer buffer = { s, length };
299 return addToStringTable<UCharBuffer, UCharBufferTranslator>(buffer);
300 } 279 }
301 280
302 struct SubstringLocation { 281 struct SubstringLocation {
303 StringImpl* baseString; 282 StringImpl* baseString;
304 unsigned start; 283 unsigned start;
305 unsigned length; 284 unsigned length;
306 }; 285 };
307 286
308 struct SubstringTranslator { 287 struct SubstringTranslator {
309 static unsigned hash(const SubstringLocation& buffer) 288 static unsigned hash(const SubstringLocation& buffer) {
310 { 289 if (buffer.baseString->is8Bit())
311 if (buffer.baseString->is8Bit()) 290 return StringHasher::computeHashAndMaskTop8Bits(buffer.baseString->charact ers8() + buffer.start, buffer.length);
312 return StringHasher::computeHashAndMaskTop8Bits(buffer.baseString->c haracters8() + buffer.start, buffer.length); 291 return StringHasher::computeHashAndMaskTop8Bits(buffer.baseString->character s16() + buffer.start, buffer.length);
313 return StringHasher::computeHashAndMaskTop8Bits(buffer.baseString->chara cters16() + buffer.start, buffer.length); 292 }
314 } 293
315 294 static bool equal(StringImpl* const& string, const SubstringLocation& buffer) {
316 static bool equal(StringImpl* const& string, const SubstringLocation& buffer ) 295 if (buffer.baseString->is8Bit())
317 { 296 return WTF::equal(string, buffer.baseString->characters8() + buffer.start, buffer.length);
318 if (buffer.baseString->is8Bit()) 297 return WTF::equal(string, buffer.baseString->characters16() + buffer.start, buffer.length);
319 return WTF::equal(string, buffer.baseString->characters8() + buffer. start, buffer.length); 298 }
320 return WTF::equal(string, buffer.baseString->characters16() + buffer.sta rt, buffer.length); 299
321 } 300 static void translate(StringImpl*& location, const SubstringLocation& buffer, unsigned hash) {
322 301 location = buffer.baseString->substring(buffer.start, buffer.length).leakRef ();
323 static void translate(StringImpl*& location, const SubstringLocation& buffer , unsigned hash) 302 location->setHash(hash);
324 { 303 location->setIsAtomic(true);
325 location = buffer.baseString->substring(buffer.start, buffer.length).lea kRef(); 304 }
326 location->setHash(hash); 305 };
327 location->setIsAtomic(true); 306
328 } 307 PassRefPtr<StringImpl> AtomicString::add(StringImpl* baseString, unsigned start, unsigned length) {
329 }; 308 if (!baseString)
330 309 return nullptr;
331 PassRefPtr<StringImpl> AtomicString::add(StringImpl* baseString, unsigned start, unsigned length) 310
332 { 311 if (!length || start >= baseString->length())
333 if (!baseString) 312 return StringImpl::empty();
334 return nullptr; 313
335 314 unsigned maxLength = baseString->length() - start;
336 if (!length || start >= baseString->length()) 315 if (length >= maxLength) {
337 return StringImpl::empty(); 316 if (!start)
338 317 return add(baseString);
339 unsigned maxLength = baseString->length() - start; 318 length = maxLength;
340 if (length >= maxLength) { 319 }
341 if (!start) 320
342 return add(baseString); 321 SubstringLocation buffer = {baseString, start, length};
343 length = maxLength; 322 return addToStringTable<SubstringLocation, SubstringTranslator>(buffer);
344 }
345
346 SubstringLocation buffer = { baseString, start, length };
347 return addToStringTable<SubstringLocation, SubstringTranslator>(buffer);
348 } 323 }
349 324
350 typedef HashTranslatorCharBuffer<LChar> LCharBuffer; 325 typedef HashTranslatorCharBuffer<LChar> LCharBuffer;
351 struct LCharBufferTranslator { 326 struct LCharBufferTranslator {
352 static unsigned hash(const LCharBuffer& buf) 327 static unsigned hash(const LCharBuffer& buf) {
353 { 328 return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length);
354 return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length); 329 }
355 } 330
356 331 static bool equal(StringImpl* const& str, const LCharBuffer& buf) {
357 static bool equal(StringImpl* const& str, const LCharBuffer& buf) 332 return WTF::equal(str, buf.s, buf.length);
358 { 333 }
359 return WTF::equal(str, buf.s, buf.length); 334
360 } 335 static void translate(StringImpl*& location, const LCharBuffer& buf, unsigned hash) {
361 336 location = StringImpl::create(buf.s, buf.length).leakRef();
362 static void translate(StringImpl*& location, const LCharBuffer& buf, unsigne d hash) 337 location->setHash(hash);
363 { 338 location->setIsAtomic(true);
364 location = StringImpl::create(buf.s, buf.length).leakRef(); 339 }
365 location->setHash(hash);
366 location->setIsAtomic(true);
367 }
368 }; 340 };
369 341
370 typedef HashTranslatorCharBuffer<char> CharBuffer; 342 typedef HashTranslatorCharBuffer<char> CharBuffer;
371 struct CharBufferFromLiteralDataTranslator { 343 struct CharBufferFromLiteralDataTranslator {
372 static unsigned hash(const CharBuffer& buf) 344 static unsigned hash(const CharBuffer& buf) {
373 { 345 return StringHasher::computeHashAndMaskTop8Bits(reinterpret_cast<const LChar *>(buf.s), buf.length);
374 return StringHasher::computeHashAndMaskTop8Bits(reinterpret_cast<const L Char*>(buf.s), buf.length); 346 }
375 } 347
376 348 static bool equal(StringImpl* const& str, const CharBuffer& buf) {
377 static bool equal(StringImpl* const& str, const CharBuffer& buf) 349 return WTF::equal(str, buf.s, buf.length);
378 { 350 }
379 return WTF::equal(str, buf.s, buf.length); 351
380 } 352 static void translate(StringImpl*& location, const CharBuffer& buf, unsigned h ash) {
381 353 location = StringImpl::create(buf.s, buf.length).leakRef();
382 static void translate(StringImpl*& location, const CharBuffer& buf, unsigned hash) 354 location->setHash(hash);
383 { 355 location->setIsAtomic(true);
384 location = StringImpl::create(buf.s, buf.length).leakRef(); 356 }
385 location->setHash(hash); 357 };
386 location->setIsAtomic(true); 358
387 } 359 PassRefPtr<StringImpl> AtomicString::add(const LChar* s, unsigned length) {
388 }; 360 if (!s)
389 361 return nullptr;
390 PassRefPtr<StringImpl> AtomicString::add(const LChar* s, unsigned length) 362
391 { 363 if (!length)
392 if (!s) 364 return StringImpl::empty();
393 return nullptr; 365
394 366 LCharBuffer buffer = {s, length};
395 if (!length) 367 return addToStringTable<LCharBuffer, LCharBufferTranslator>(buffer);
396 return StringImpl::empty(); 368 }
397 369
398 LCharBuffer buffer = { s, length }; 370 PassRefPtr<StringImpl> AtomicString::addFromLiteralData(const char* characters, unsigned length) {
399 return addToStringTable<LCharBuffer, LCharBufferTranslator>(buffer); 371 ASSERT(characters);
400 } 372 ASSERT(length);
401 373
402 PassRefPtr<StringImpl> AtomicString::addFromLiteralData(const char* characters, unsigned length) 374 CharBuffer buffer = {characters, length};
403 { 375 return addToStringTable<CharBuffer, CharBufferFromLiteralDataTranslator>(buffe r);
404 ASSERT(characters); 376 }
405 ASSERT(length); 377
406 378 PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* string) {
407 CharBuffer buffer = { characters, length }; 379 return atomicStringTable().addStringImpl(string);
408 return addToStringTable<CharBuffer, CharBufferFromLiteralDataTranslator>(buf fer); 380 }
409 } 381
410 382 template <typename CharacterType>
411 PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* string) 383 static inline HashSet<StringImpl*>::iterator findString(const StringImpl* string Impl) {
412 { 384 HashAndCharacters<CharacterType> buffer = {stringImpl->existingHash(), stringI mpl->getCharacters<CharacterType>(), stringImpl->length()};
413 return atomicStringTable().addStringImpl(string); 385 return atomicStrings().find<HashAndCharactersTranslator<CharacterType>>(buffer );
414 } 386 }
415 387
416 template<typename CharacterType> 388 StringImpl* AtomicString::find(const StringImpl* stringImpl) {
417 static inline HashSet<StringImpl*>::iterator findString(const StringImpl* string Impl) 389 ASSERT(stringImpl);
418 { 390 ASSERT(stringImpl->existingHash());
419 HashAndCharacters<CharacterType> buffer = { stringImpl->existingHash(), stri ngImpl->getCharacters<CharacterType>(), stringImpl->length() }; 391
420 return atomicStrings().find<HashAndCharactersTranslator<CharacterType>>(buff er); 392 if (!stringImpl->length())
421 } 393 return StringImpl::empty();
422 394
423 StringImpl* AtomicString::find(const StringImpl* stringImpl) 395 HashSet<StringImpl*>::iterator iterator;
424 { 396 if (stringImpl->is8Bit())
425 ASSERT(stringImpl); 397 iterator = findString<LChar>(stringImpl);
426 ASSERT(stringImpl->existingHash()); 398 else
427 399 iterator = findString<UChar>(stringImpl);
428 if (!stringImpl->length()) 400 if (iterator == atomicStrings().end())
429 return StringImpl::empty(); 401 return 0;
430 402 return *iterator;
431 HashSet<StringImpl*>::iterator iterator; 403 }
432 if (stringImpl->is8Bit()) 404
433 iterator = findString<LChar>(stringImpl); 405 void AtomicString::remove(StringImpl* r) {
434 else 406 HashSet<StringImpl*>::iterator iterator;
435 iterator = findString<UChar>(stringImpl); 407 if (r->is8Bit())
436 if (iterator == atomicStrings().end()) 408 iterator = findString<LChar>(r);
437 return 0; 409 else
438 return *iterator; 410 iterator = findString<UChar>(r);
439 } 411 RELEASE_ASSERT(iterator != atomicStrings().end());
440 412 atomicStrings().remove(iterator);
441 void AtomicString::remove(StringImpl* r) 413 }
442 { 414
443 HashSet<StringImpl*>::iterator iterator; 415 AtomicString AtomicString::lower() const {
444 if (r->is8Bit()) 416 // Note: This is a hot function in the Dromaeo benchmark.
445 iterator = findString<LChar>(r); 417 StringImpl* impl = this->impl();
446 else 418 if (UNLIKELY(!impl))
447 iterator = findString<UChar>(r); 419 return *this;
448 RELEASE_ASSERT(iterator != atomicStrings().end()); 420 RefPtr<StringImpl> newImpl = impl->lower();
449 atomicStrings().remove(iterator); 421 if (LIKELY(newImpl == impl))
450 } 422 return *this;
451 423 return AtomicString(newImpl.release());
452 AtomicString AtomicString::lower() const 424 }
453 { 425
454 // Note: This is a hot function in the Dromaeo benchmark. 426 AtomicString AtomicString::fromUTF8Internal(const char* charactersStart, const c har* charactersEnd) {
455 StringImpl* impl = this->impl(); 427 HashAndUTF8Characters buffer;
456 if (UNLIKELY(!impl)) 428 buffer.characters = charactersStart;
457 return *this; 429 buffer.hash = calculateStringHashAndLengthFromUTF8MaskingTop8Bits(charactersSt art, charactersEnd, buffer.length, buffer.utf16Length);
458 RefPtr<StringImpl> newImpl = impl->lower(); 430
459 if (LIKELY(newImpl == impl)) 431 if (!buffer.hash)
460 return *this; 432 return nullAtom;
461 return AtomicString(newImpl.release()); 433
462 } 434 AtomicString atomicString;
463 435 atomicString.m_string = addToStringTable<HashAndUTF8Characters, HashAndUTF8Cha ractersTranslator>(buffer);
464 AtomicString AtomicString::fromUTF8Internal(const char* charactersStart, const c har* charactersEnd) 436 return atomicString;
465 { 437 }
466 HashAndUTF8Characters buffer; 438
467 buffer.characters = charactersStart; 439 AtomicString AtomicString::number(int number) {
468 buffer.hash = calculateStringHashAndLengthFromUTF8MaskingTop8Bits(characters Start, charactersEnd, buffer.length, buffer.utf16Length); 440 return numberToStringSigned<AtomicString>(number);
469 441 }
470 if (!buffer.hash) 442
471 return nullAtom; 443 AtomicString AtomicString::number(unsigned number) {
472 444 return numberToStringUnsigned<AtomicString>(number);
473 AtomicString atomicString; 445 }
474 atomicString.m_string = addToStringTable<HashAndUTF8Characters, HashAndUTF8C haractersTranslator>(buffer); 446
475 return atomicString; 447 AtomicString AtomicString::number(long number) {
476 } 448 return numberToStringSigned<AtomicString>(number);
477 449 }
478 AtomicString AtomicString::number(int number) 450
479 { 451 AtomicString AtomicString::number(unsigned long number) {
480 return numberToStringSigned<AtomicString>(number); 452 return numberToStringUnsigned<AtomicString>(number);
481 } 453 }
482 454
483 AtomicString AtomicString::number(unsigned number) 455 AtomicString AtomicString::number(long long number) {
484 { 456 return numberToStringSigned<AtomicString>(number);
485 return numberToStringUnsigned<AtomicString>(number); 457 }
486 } 458
487 459 AtomicString AtomicString::number(unsigned long long number) {
488 AtomicString AtomicString::number(long number) 460 return numberToStringUnsigned<AtomicString>(number);
489 { 461 }
490 return numberToStringSigned<AtomicString>(number); 462
491 } 463 AtomicString AtomicString::number(double number, unsigned precision, TrailingZer osTruncatingPolicy trailingZerosTruncatingPolicy) {
492 464 NumberToStringBuffer buffer;
493 AtomicString AtomicString::number(unsigned long number) 465 return AtomicString(numberToFixedPrecisionString(number, precision, buffer, tr ailingZerosTruncatingPolicy == TruncateTrailingZeros));
494 {
495 return numberToStringUnsigned<AtomicString>(number);
496 }
497
498 AtomicString AtomicString::number(long long number)
499 {
500 return numberToStringSigned<AtomicString>(number);
501 }
502
503 AtomicString AtomicString::number(unsigned long long number)
504 {
505 return numberToStringUnsigned<AtomicString>(number);
506 }
507
508 AtomicString AtomicString::number(double number, unsigned precision, TrailingZer osTruncatingPolicy trailingZerosTruncatingPolicy)
509 {
510 NumberToStringBuffer buffer;
511 return AtomicString(numberToFixedPrecisionString(number, precision, buffer, trailingZerosTruncatingPolicy == TruncateTrailingZeros));
512 } 466 }
513 467
514 #ifndef NDEBUG 468 #ifndef NDEBUG
515 void AtomicString::show() const 469 void AtomicString::show() const {
516 { 470 m_string.show();
517 m_string.show();
518 } 471 }
519 #endif 472 #endif
520 473
521 } // namespace WTF 474 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/AtomicString.h ('k') | third_party/WebKit/Source/wtf/text/AtomicStringCF.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698