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

Side by Side Diff: third_party/WebKit/Source/wtf/text/StringBuilder.h

Issue 1611343002: wtf reformat test Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: pydent Created 4 years, 11 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 16 matching lines...) Expand all
27 #ifndef StringBuilder_h 27 #ifndef StringBuilder_h
28 #define StringBuilder_h 28 #define StringBuilder_h
29 29
30 #include "wtf/WTFExport.h" 30 #include "wtf/WTFExport.h"
31 #include "wtf/text/AtomicString.h" 31 #include "wtf/text/AtomicString.h"
32 #include "wtf/text/WTFString.h" 32 #include "wtf/text/WTFString.h"
33 33
34 namespace WTF { 34 namespace WTF {
35 35
36 class WTF_EXPORT StringBuilder { 36 class WTF_EXPORT StringBuilder {
37 // Disallow copying since it's expensive and we don't want code to do it by accident. 37 // Disallow copying since it's expensive and we don't want code to do it by ac cident.
38 WTF_MAKE_NONCOPYABLE(StringBuilder); 38 WTF_MAKE_NONCOPYABLE(StringBuilder);
39 39
40 public: 40 public:
41 StringBuilder() 41 StringBuilder() : m_bufferCharacters8(0), m_length(0), m_is8Bit(true) {}
42 : m_bufferCharacters8(0) 42
43 , m_length(0) 43 void append(const UChar*, unsigned);
44 , m_is8Bit(true) 44 void append(const LChar*, unsigned);
45 { 45
46 } 46 ALWAYS_INLINE void append(const char* characters, unsigned length) {
47 47 append(reinterpret_cast<const LChar*>(characters), length);
48 void append(const UChar*, unsigned); 48 }
49 void append(const LChar*, unsigned); 49
50 50 void append(const String& string) {
51 ALWAYS_INLINE void append(const char* characters, unsigned length) { append( reinterpret_cast<const LChar*>(characters), length); } 51 if (!string.length())
52 52 return;
53 void append(const String& string) 53
54 { 54 // If we're appending to an empty string, and there is not a buffer (reserve Capacity has not been called)
55 if (!string.length()) 55 // then just retain the string.
56 return; 56 if (!m_length && !m_buffer) {
57 57 m_string = string;
58 // If we're appending to an empty string, and there is not a buffer (res erveCapacity has not been called) 58 m_length = string.length();
59 // then just retain the string. 59 m_is8Bit = m_string.is8Bit();
60 if (!m_length && !m_buffer) { 60 return;
61 m_string = string; 61 }
62 m_length = string.length(); 62
63 m_is8Bit = m_string.is8Bit(); 63 if (string.is8Bit())
64 return; 64 append(string.characters8(), string.length());
65 } 65 else
66 66 append(string.characters16(), string.length());
67 if (string.is8Bit()) 67 }
68 append(string.characters8(), string.length()); 68
69 else 69 void append(const StringBuilder& other) {
70 append(string.characters16(), string.length()); 70 if (!other.m_length)
71 } 71 return;
72 72
73 void append(const StringBuilder& other) 73 // If we're appending to an empty string, and there is not a buffer (reserve Capacity has not been called)
74 { 74 // then just retain the string.
75 if (!other.m_length) 75 if (!m_length && !m_buffer && !other.m_string.isNull()) {
76 return; 76 m_string = other.m_string;
77 77 m_length = other.m_length;
78 // If we're appending to an empty string, and there is not a buffer (res erveCapacity has not been called) 78 return;
79 // then just retain the string. 79 }
80 if (!m_length && !m_buffer && !other.m_string.isNull()) { 80
81 m_string = other.m_string; 81 if (other.is8Bit())
82 m_length = other.m_length; 82 append(other.characters8(), other.m_length);
83 return; 83 else
84 } 84 append(other.characters16(), other.m_length);
85 85 }
86 if (other.is8Bit()) 86
87 append(other.characters8(), other.m_length); 87 void append(const String& string, unsigned offset, unsigned length) {
88 else 88 if (!string.length())
89 append(other.characters16(), other.m_length); 89 return;
90 } 90
91 91 unsigned extent = offset + length;
92 void append(const String& string, unsigned offset, unsigned length) 92 if (extent < offset || extent > string.length())
93 { 93 return;
94 if (!string.length()) 94
95 return; 95 if (string.is8Bit())
96 96 append(string.characters8() + offset, length);
97 unsigned extent = offset + length; 97 else
98 if (extent < offset || extent > string.length()) 98 append(string.characters16() + offset, length);
99 return; 99 }
100 100
101 if (string.is8Bit()) 101 void append(const StringView& string) {
102 append(string.characters8() + offset, length); 102 if (!string.length())
103 else 103 return;
104 append(string.characters16() + offset, length); 104
105 } 105 if (string.is8Bit())
106 106 append(string.characters8(), string.length());
107 void append(const StringView& string) 107 else
108 { 108 append(string.characters16(), string.length());
109 if (!string.length()) 109 }
110 return; 110
111 111 void append(const char* characters) {
112 if (string.is8Bit()) 112 if (characters)
113 append(string.characters8(), string.length()); 113 append(characters, strlen(characters));
114 else 114 }
115 append(string.characters16(), string.length()); 115
116 } 116 void append(UChar c) {
117 117 if (m_buffer && m_length < m_buffer->length() && m_string.isNull()) {
118 void append(const char* characters) 118 if (!m_is8Bit) {
119 { 119 m_bufferCharacters16[m_length++] = c;
120 if (characters) 120 return;
121 append(characters, strlen(characters)); 121 }
122 } 122
123 123 if (!(c & ~0xff)) {
124 void append(UChar c) 124 m_bufferCharacters8[m_length++] = static_cast<LChar>(c);
125 { 125 return;
126 if (m_buffer && m_length < m_buffer->length() && m_string.isNull()) { 126 }
127 if (!m_is8Bit) { 127 }
128 m_bufferCharacters16[m_length++] = c; 128 append(&c, 1);
129 return; 129 }
130 } 130
131 131 void append(LChar c) {
132 if (!(c & ~0xff)) { 132 if (m_buffer && m_length < m_buffer->length() && m_string.isNull()) {
133 m_bufferCharacters8[m_length++] = static_cast<LChar>(c); 133 if (m_is8Bit)
134 return; 134 m_bufferCharacters8[m_length++] = c;
135 } 135 else
136 } 136 m_bufferCharacters16[m_length++] = c;
137 append(&c, 1); 137 } else {
138 } 138 append(&c, 1);
139 139 }
140 void append(LChar c) 140 }
141 { 141
142 if (m_buffer && m_length < m_buffer->length() && m_string.isNull()) { 142 void append(char c) { append(static_cast<LChar>(c)); }
143 if (m_is8Bit) 143
144 m_bufferCharacters8[m_length++] = c; 144 void append(UChar32 c) {
145 else 145 if (U_IS_BMP(c)) {
146 m_bufferCharacters16[m_length++] = c; 146 append(static_cast<UChar>(c));
147 } else { 147 return;
148 append(&c, 1); 148 }
149 } 149 append(U16_LEAD(c));
150 } 150 append(U16_TRAIL(c));
151 151 }
152 void append(char c) 152
153 { 153 template <unsigned charactersCount>
154 append(static_cast<LChar>(c)); 154 ALWAYS_INLINE void appendLiteral(const char (&characters)[charactersCount]) {
155 } 155 append(characters, charactersCount - 1);
156 156 }
157 void append(UChar32 c) 157
158 { 158 void appendNumber(int);
159 if (U_IS_BMP(c)) { 159 void appendNumber(unsigned);
160 append(static_cast<UChar>(c)); 160 void appendNumber(long);
161 return; 161 void appendNumber(unsigned long);
162 } 162 void appendNumber(long long);
163 append(U16_LEAD(c)); 163 void appendNumber(unsigned long long);
164 append(U16_TRAIL(c)); 164 void appendNumber(double,
165 } 165 unsigned precision = 6,
166 166 TrailingZerosTruncatingPolicy = TruncateTrailingZeros);
167 template<unsigned charactersCount> 167
168 ALWAYS_INLINE void appendLiteral(const char (&characters)[charactersCount]) { append(characters, charactersCount - 1); } 168 String toString() {
169 169 shrinkToFit();
170 void appendNumber(int); 170 if (m_string.isNull())
171 void appendNumber(unsigned); 171 reifyString();
172 void appendNumber(long); 172 return m_string;
173 void appendNumber(unsigned long); 173 }
174 void appendNumber(long long); 174
175 void appendNumber(unsigned long long); 175 String substring(unsigned position, unsigned length) const {
176 void appendNumber(double, unsigned precision = 6, TrailingZerosTruncatingPol icy = TruncateTrailingZeros); 176 if (!m_length)
177 177 return emptyString();
178 String toString() 178 if (!m_string.isNull())
179 { 179 return m_string.substring(position, length);
180 shrinkToFit(); 180 return reifySubstring(position, length);
181 if (m_string.isNull()) 181 }
182 reifyString(); 182
183 return m_string; 183 AtomicString toAtomicString() const {
184 } 184 if (!m_length)
185 185 return emptyAtom;
186 String substring(unsigned position, unsigned length) const 186
187 { 187 // If the buffer is sufficiently over-allocated, make a new AtomicString fro m a copy so its buffer is not so large.
188 if (!m_length) 188 if (canShrink()) {
189 return emptyString(); 189 if (is8Bit())
190 if (!m_string.isNull()) 190 return AtomicString(characters8(), length());
191 return m_string.substring(position, length); 191 return AtomicString(characters16(), length());
192 return reifySubstring(position, length); 192 }
193 } 193
194 194 if (!m_string.isNull())
195 AtomicString toAtomicString() const 195 return AtomicString(m_string);
196 { 196
197 if (!m_length) 197 ASSERT(m_buffer);
198 return emptyAtom; 198 return AtomicString(m_buffer.get(), 0, m_length);
199 199 }
200 // If the buffer is sufficiently over-allocated, make a new AtomicString from a copy so its buffer is not so large. 200
201 if (canShrink()) { 201 unsigned length() const { return m_length; }
202 if (is8Bit()) 202
203 return AtomicString(characters8(), length()); 203 bool isEmpty() const { return !m_length; }
204 return AtomicString(characters16(), length()); 204
205 } 205 void reserveCapacity(unsigned newCapacity);
206 206
207 if (!m_string.isNull()) 207 unsigned capacity() const { return m_buffer ? m_buffer->length() : m_length; }
208 return AtomicString(m_string); 208
209 209 void resize(unsigned newSize);
210 ASSERT(m_buffer); 210
211 return AtomicString(m_buffer.get(), 0, m_length); 211 bool canShrink() const;
212 } 212
213 213 void shrinkToFit();
214 unsigned length() const 214
215 { 215 UChar operator[](unsigned i) const {
216 return m_length; 216 ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
217 } 217 if (m_is8Bit)
218 218 return characters8()[i];
219 bool isEmpty() const { return !m_length; } 219 return characters16()[i];
220 220 }
221 void reserveCapacity(unsigned newCapacity); 221
222 222 const LChar* characters8() const {
223 unsigned capacity() const 223 ASSERT(m_is8Bit);
224 { 224 if (!m_length)
225 return m_buffer ? m_buffer->length() : m_length; 225 return 0;
226 } 226 if (!m_string.isNull())
227 227 return m_string.characters8();
228 void resize(unsigned newSize); 228 ASSERT(m_buffer);
229 229 return m_buffer->characters8();
230 bool canShrink() const; 230 }
231 231
232 void shrinkToFit(); 232 const UChar* characters16() const {
233 233 ASSERT(!m_is8Bit);
234 UChar operator[](unsigned i) const 234 if (!m_length)
235 { 235 return 0;
236 ASSERT_WITH_SECURITY_IMPLICATION(i < m_length); 236 if (!m_string.isNull())
237 if (m_is8Bit) 237 return m_string.characters16();
238 return characters8()[i]; 238 ASSERT(m_buffer);
239 return characters16()[i]; 239 return m_buffer->characters16();
240 } 240 }
241 241
242 const LChar* characters8() const 242 bool is8Bit() const { return m_is8Bit; }
243 { 243
244 ASSERT(m_is8Bit); 244 void clear() {
245 if (!m_length) 245 m_length = 0;
246 return 0; 246 m_string = String();
247 if (!m_string.isNull()) 247 m_buffer = nullptr;
248 return m_string.characters8(); 248 m_bufferCharacters8 = 0;
249 ASSERT(m_buffer); 249 m_is8Bit = true;
250 return m_buffer->characters8(); 250 }
251 } 251
252 252 void swap(StringBuilder& stringBuilder) {
253 const UChar* characters16() const 253 std::swap(m_length, stringBuilder.m_length);
254 { 254 m_string.swap(stringBuilder.m_string);
255 ASSERT(!m_is8Bit); 255 m_buffer.swap(stringBuilder.m_buffer);
256 if (!m_length) 256 std::swap(m_is8Bit, stringBuilder.m_is8Bit);
257 return 0; 257 std::swap(m_bufferCharacters8, stringBuilder.m_bufferCharacters8);
258 if (!m_string.isNull()) 258 }
259 return m_string.characters16(); 259
260 ASSERT(m_buffer); 260 private:
261 return m_buffer->characters16(); 261 void allocateBuffer(const LChar* currentCharacters, unsigned requiredLength);
262 } 262 void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength);
263 263 void allocateBufferUpConvert(const LChar* currentCharacters,
264 bool is8Bit() const { return m_is8Bit; } 264 unsigned requiredLength);
265 265 template <typename CharType>
266 void clear() 266 void reallocateBuffer(unsigned requiredLength);
267 { 267 template <typename CharType>
268 m_length = 0; 268 ALWAYS_INLINE CharType* appendUninitialized(unsigned length);
269 m_string = String(); 269 template <typename CharType>
270 m_buffer = nullptr; 270 CharType* appendUninitializedSlow(unsigned length);
271 m_bufferCharacters8 = 0; 271 template <typename CharType>
272 m_is8Bit = true; 272 ALWAYS_INLINE CharType* getBufferCharacters();
273 } 273 void reifyString();
274 274 String reifySubstring(unsigned position, unsigned length) const;
275 void swap(StringBuilder& stringBuilder) 275
276 { 276 String m_string; // Pointers first: crbug.com/232031
277 std::swap(m_length, stringBuilder.m_length); 277 RefPtr<StringImpl> m_buffer;
278 m_string.swap(stringBuilder.m_string); 278 union {
279 m_buffer.swap(stringBuilder.m_buffer); 279 LChar* m_bufferCharacters8;
280 std::swap(m_is8Bit, stringBuilder.m_is8Bit); 280 UChar* m_bufferCharacters16;
281 std::swap(m_bufferCharacters8, stringBuilder.m_bufferCharacters8); 281 };
282 } 282 unsigned m_length;
283 283 bool m_is8Bit;
284 private:
285 void allocateBuffer(const LChar* currentCharacters, unsigned requiredLength) ;
286 void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength) ;
287 void allocateBufferUpConvert(const LChar* currentCharacters, unsigned requir edLength);
288 template <typename CharType>
289 void reallocateBuffer(unsigned requiredLength);
290 template <typename CharType>
291 ALWAYS_INLINE CharType* appendUninitialized(unsigned length);
292 template <typename CharType>
293 CharType* appendUninitializedSlow(unsigned length);
294 template <typename CharType>
295 ALWAYS_INLINE CharType * getBufferCharacters();
296 void reifyString();
297 String reifySubstring(unsigned position, unsigned length) const;
298
299 String m_string; // Pointers first: crbug.com/232031
300 RefPtr<StringImpl> m_buffer;
301 union {
302 LChar* m_bufferCharacters8;
303 UChar* m_bufferCharacters16;
304 };
305 unsigned m_length;
306 bool m_is8Bit;
307 }; 284 };
308 285
309 template <> 286 template <>
310 ALWAYS_INLINE LChar* StringBuilder::getBufferCharacters<LChar>() 287 ALWAYS_INLINE LChar* StringBuilder::getBufferCharacters<LChar>() {
311 { 288 ASSERT(m_is8Bit);
312 ASSERT(m_is8Bit); 289 return m_bufferCharacters8;
313 return m_bufferCharacters8;
314 } 290 }
315 291
316 template <> 292 template <>
317 ALWAYS_INLINE UChar* StringBuilder::getBufferCharacters<UChar>() 293 ALWAYS_INLINE UChar* StringBuilder::getBufferCharacters<UChar>() {
318 { 294 ASSERT(!m_is8Bit);
319 ASSERT(!m_is8Bit); 295 return m_bufferCharacters16;
320 return m_bufferCharacters16;
321 } 296 }
322 297
323 template <typename CharType> 298 template <typename CharType>
324 bool equal(const StringBuilder& s, const CharType* buffer, unsigned length) 299 bool equal(const StringBuilder& s, const CharType* buffer, unsigned length) {
325 { 300 if (s.length() != length)
326 if (s.length() != length) 301 return false;
327 return false; 302
328 303 if (s.is8Bit())
329 if (s.is8Bit()) 304 return equal(s.characters8(), buffer, length);
330 return equal(s.characters8(), buffer, length); 305
331 306 return equal(s.characters16(), buffer, length);
332 return equal(s.characters16(), buffer, length); 307 }
333 } 308
334 309 template <typename CharType>
335 template<typename CharType> 310 bool equalIgnoringCase(const StringBuilder& s,
336 bool equalIgnoringCase(const StringBuilder& s, const CharType* buffer, unsigned length) 311 const CharType* buffer,
337 { 312 unsigned length) {
338 if (s.length() != length) 313 if (s.length() != length)
339 return false; 314 return false;
340 315
341 if (s.is8Bit()) 316 if (s.is8Bit())
342 return equalIgnoringCase(s.characters8(), buffer, length); 317 return equalIgnoringCase(s.characters8(), buffer, length);
343 318
344 return equalIgnoringCase(s.characters16(), buffer, length); 319 return equalIgnoringCase(s.characters16(), buffer, length);
345 } 320 }
346 321
347 inline bool equalIgnoringCase(const StringBuilder& s, const char* string) 322 inline bool equalIgnoringCase(const StringBuilder& s, const char* string) {
348 { 323 return equalIgnoringCase(s, reinterpret_cast<const LChar*>(string),
349 return equalIgnoringCase(s, reinterpret_cast<const LChar*>(string), strlen(s tring)); 324 strlen(string));
350 } 325 }
351 326
352 template <typename StringType> 327 template <typename StringType>
353 bool equal(const StringBuilder& a, const StringType& b) 328 bool equal(const StringBuilder& a, const StringType& b) {
354 { 329 if (a.length() != b.length())
355 if (a.length() != b.length()) 330 return false;
356 return false; 331
357 332 if (!a.length())
358 if (!a.length()) 333 return true;
359 return true; 334
360 335 if (a.is8Bit()) {
361 if (a.is8Bit()) {
362 if (b.is8Bit())
363 return equal(a.characters8(), b.characters8(), a.length());
364 return equal(a.characters8(), b.characters16(), a.length());
365 }
366
367 if (b.is8Bit()) 336 if (b.is8Bit())
368 return equal(a.characters16(), b.characters8(), a.length()); 337 return equal(a.characters8(), b.characters8(), a.length());
369 return equal(a.characters16(), b.characters16(), a.length()); 338 return equal(a.characters8(), b.characters16(), a.length());
339 }
340
341 if (b.is8Bit())
342 return equal(a.characters16(), b.characters8(), a.length());
343 return equal(a.characters16(), b.characters16(), a.length());
370 } 344 }
371 345
372 template <typename StringType> 346 template <typename StringType>
373 bool equalIgnoringCase(const StringBuilder& a, const StringType& b) 347 bool equalIgnoringCase(const StringBuilder& a, const StringType& b) {
374 { 348 if (a.length() != b.length())
375 if (a.length() != b.length()) 349 return false;
376 return false; 350
377 351 if (!a.length())
378 if (!a.length()) 352 return true;
379 return true; 353
380 354 if (a.is8Bit()) {
381 if (a.is8Bit()) {
382 if (b.is8Bit())
383 return equalIgnoringCase(a.characters8(), b.characters8(), a.length( ));
384 return equalIgnoringCase(a.characters8(), b.characters16(), a.length());
385 }
386
387 if (b.is8Bit()) 355 if (b.is8Bit())
388 return equalIgnoringCase(a.characters16(), b.characters8(), a.length()); 356 return equalIgnoringCase(a.characters8(), b.characters8(), a.length());
389 return equalIgnoringCase(a.characters16(), b.characters16(), a.length()); 357 return equalIgnoringCase(a.characters8(), b.characters16(), a.length());
390 } 358 }
391 359
392 inline bool operator==(const StringBuilder& a, const StringBuilder& b) { return equal(a, b); } 360 if (b.is8Bit())
393 inline bool operator!=(const StringBuilder& a, const StringBuilder& b) { return !equal(a, b); } 361 return equalIgnoringCase(a.characters16(), b.characters8(), a.length());
394 inline bool operator==(const StringBuilder& a, const String& b) { return equal(a , b); } 362 return equalIgnoringCase(a.characters16(), b.characters16(), a.length());
395 inline bool operator!=(const StringBuilder& a, const String& b) { return !equal( a, b); } 363 }
396 inline bool operator==(const String& a, const StringBuilder& b) { return equal(b , a); } 364
397 inline bool operator!=(const String& a, const StringBuilder& b) { return !equal( b, a); } 365 inline bool operator==(const StringBuilder& a, const StringBuilder& b) {
398 366 return equal(a, b);
399 } // namespace WTF 367 }
368 inline bool operator!=(const StringBuilder& a, const StringBuilder& b) {
369 return !equal(a, b);
370 }
371 inline bool operator==(const StringBuilder& a, const String& b) {
372 return equal(a, b);
373 }
374 inline bool operator!=(const StringBuilder& a, const String& b) {
375 return !equal(a, b);
376 }
377 inline bool operator==(const String& a, const StringBuilder& b) {
378 return equal(b, a);
379 }
380 inline bool operator!=(const String& a, const StringBuilder& b) {
381 return !equal(b, a);
382 }
383
384 } // namespace WTF
400 385
401 using WTF::StringBuilder; 386 using WTF::StringBuilder;
402 387
403 #endif // StringBuilder_h 388 #endif // StringBuilder_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/StringBufferTest.cpp ('k') | third_party/WebKit/Source/wtf/text/StringBuilder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698