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

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

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) 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()
42 : m_bufferCharacters8(0) 42 : m_bufferCharacters8(0), m_length(0), m_is8Bit(true) {
43 , m_length(0) 43 }
44 , m_is8Bit(true) 44
45 { 45 void append(const UChar*, unsigned);
46 } 46 void append(const LChar*, unsigned);
47 47
48 void append(const UChar*, unsigned); 48 ALWAYS_INLINE void append(const char* characters, unsigned length) { append(re interpret_cast<const LChar*>(characters), length); }
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) {
143 if (m_is8Bit) 143 append(static_cast<LChar>(c));
144 m_bufferCharacters8[m_length++] = c; 144 }
145 else 145
146 m_bufferCharacters16[m_length++] = c; 146 void append(UChar32 c) {
147 } else { 147 if (U_IS_BMP(c)) {
148 append(&c, 1); 148 append(static_cast<UChar>(c));
149 } 149 return;
150 } 150 }
151 151 append(U16_LEAD(c));
152 void append(char c) 152 append(U16_TRAIL(c));
153 { 153 }
154 append(static_cast<LChar>(c)); 154
155 } 155 template <unsigned charactersCount>
156 156 ALWAYS_INLINE void appendLiteral(const char(&characters)[charactersCount]) { a ppend(characters, charactersCount - 1); }
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, unsigned precision = 6, TrailingZerosTruncatingPolic y = TruncateTrailingZeros);
165 } 165
166 166 String toString() {
167 template<unsigned charactersCount> 167 shrinkToFit();
168 ALWAYS_INLINE void appendLiteral(const char (&characters)[charactersCount]) { append(characters, charactersCount - 1); } 168 if (m_string.isNull())
169 169 reifyString();
170 void appendNumber(int); 170 return m_string;
171 void appendNumber(unsigned); 171 }
172 void appendNumber(long); 172
173 void appendNumber(unsigned long); 173 String substring(unsigned position, unsigned length) const {
174 void appendNumber(long long); 174 if (!m_length)
175 void appendNumber(unsigned long long); 175 return emptyString();
176 void appendNumber(double, unsigned precision = 6, TrailingZerosTruncatingPol icy = TruncateTrailingZeros); 176 if (!m_string.isNull())
177 177 return m_string.substring(position, length);
178 String toString() 178 return reifySubstring(position, length);
179 { 179 }
180 shrinkToFit(); 180
181 if (m_string.isNull()) 181 AtomicString toAtomicString() const {
182 reifyString(); 182 if (!m_length)
183 return m_string; 183 return emptyAtom;
184 } 184
185 185 // If the buffer is sufficiently over-allocated, make a new AtomicString fro m a copy so its buffer is not so large.
186 String substring(unsigned position, unsigned length) const 186 if (canShrink()) {
187 { 187 if (is8Bit())
188 if (!m_length) 188 return AtomicString(characters8(), length());
189 return emptyString(); 189 return AtomicString(characters16(), length());
190 if (!m_string.isNull()) 190 }
191 return m_string.substring(position, length); 191
192 return reifySubstring(position, length); 192 if (!m_string.isNull())
193 } 193 return AtomicString(m_string);
194 194
195 AtomicString toAtomicString() const 195 ASSERT(m_buffer);
196 { 196 return AtomicString(m_buffer.get(), 0, m_length);
197 if (!m_length) 197 }
198 return emptyAtom; 198
199 199 unsigned length() const {
200 // If the buffer is sufficiently over-allocated, make a new AtomicString from a copy so its buffer is not so large. 200 return m_length;
201 if (canShrink()) { 201 }
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 {
208 return AtomicString(m_string); 208 return m_buffer ? m_buffer->length() : m_length;
209 209 }
210 ASSERT(m_buffer); 210
211 return AtomicString(m_buffer.get(), 0, m_length); 211 void resize(unsigned newSize);
212 } 212
213 213 bool canShrink() const;
214 unsigned length() const 214
215 { 215 void shrinkToFit();
216 return m_length; 216
217 } 217 UChar operator[](unsigned i) const {
218 218 ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
219 bool isEmpty() const { return !m_length; } 219 if (m_is8Bit)
220 220 return characters8()[i];
221 void reserveCapacity(unsigned newCapacity); 221 return characters16()[i];
222 222 }
223 unsigned capacity() const 223
224 { 224 const LChar* characters8() const {
225 return m_buffer ? m_buffer->length() : m_length; 225 ASSERT(m_is8Bit);
226 } 226 if (!m_length)
227 227 return 0;
228 void resize(unsigned newSize); 228 if (!m_string.isNull())
229 229 return m_string.characters8();
230 bool canShrink() const; 230 ASSERT(m_buffer);
231 231 return m_buffer->characters8();
232 void shrinkToFit(); 232 }
233 233
234 UChar operator[](unsigned i) const 234 const UChar* characters16() const {
235 { 235 ASSERT(!m_is8Bit);
236 ASSERT_WITH_SECURITY_IMPLICATION(i < m_length); 236 if (!m_length)
237 if (m_is8Bit) 237 return 0;
238 return characters8()[i]; 238 if (!m_string.isNull())
239 return characters16()[i]; 239 return m_string.characters16();
240 } 240 ASSERT(m_buffer);
241 241 return m_buffer->characters16();
242 const LChar* characters8() const 242 }
243 { 243
244 ASSERT(m_is8Bit); 244 bool is8Bit() const { return m_is8Bit; }
245 if (!m_length) 245
246 return 0; 246 void clear() {
247 if (!m_string.isNull()) 247 m_length = 0;
248 return m_string.characters8(); 248 m_string = String();
249 ASSERT(m_buffer); 249 m_buffer = nullptr;
250 return m_buffer->characters8(); 250 m_bufferCharacters8 = 0;
251 } 251 m_is8Bit = true;
252 252 }
253 const UChar* characters16() const 253
254 { 254 void swap(StringBuilder& stringBuilder) {
255 ASSERT(!m_is8Bit); 255 std::swap(m_length, stringBuilder.m_length);
256 if (!m_length) 256 m_string.swap(stringBuilder.m_string);
257 return 0; 257 m_buffer.swap(stringBuilder.m_buffer);
258 if (!m_string.isNull()) 258 std::swap(m_is8Bit, stringBuilder.m_is8Bit);
259 return m_string.characters16(); 259 std::swap(m_bufferCharacters8, stringBuilder.m_bufferCharacters8);
260 ASSERT(m_buffer); 260 }
261 return m_buffer->characters16(); 261
262 } 262 private:
263 263 void allocateBuffer(const LChar* currentCharacters, unsigned requiredLength);
264 bool is8Bit() const { return m_is8Bit; } 264 void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength);
265 265 void allocateBufferUpConvert(const LChar* currentCharacters, unsigned required Length);
266 void clear() 266 template <typename CharType>
267 { 267 void reallocateBuffer(unsigned requiredLength);
268 m_length = 0; 268 template <typename CharType>
269 m_string = String(); 269 ALWAYS_INLINE CharType* appendUninitialized(unsigned length);
270 m_buffer = nullptr; 270 template <typename CharType>
271 m_bufferCharacters8 = 0; 271 CharType* appendUninitializedSlow(unsigned length);
272 m_is8Bit = true; 272 template <typename CharType>
273 } 273 ALWAYS_INLINE CharType* getBufferCharacters();
274 274 void reifyString();
275 void swap(StringBuilder& stringBuilder) 275 String reifySubstring(unsigned position, unsigned length) const;
276 { 276
277 std::swap(m_length, stringBuilder.m_length); 277 String m_string; // Pointers first: crbug.com/232031
278 m_string.swap(stringBuilder.m_string); 278 RefPtr<StringImpl> m_buffer;
279 m_buffer.swap(stringBuilder.m_buffer); 279 union {
280 std::swap(m_is8Bit, stringBuilder.m_is8Bit); 280 LChar* m_bufferCharacters8;
281 std::swap(m_bufferCharacters8, stringBuilder.m_bufferCharacters8); 281 UChar* m_bufferCharacters16;
282 } 282 };
283 283 unsigned m_length;
284 private: 284 bool m_is8Bit;
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 }; 285 };
308 286
309 template <> 287 template <>
310 ALWAYS_INLINE LChar* StringBuilder::getBufferCharacters<LChar>() 288 ALWAYS_INLINE LChar* StringBuilder::getBufferCharacters<LChar>() {
311 { 289 ASSERT(m_is8Bit);
312 ASSERT(m_is8Bit); 290 return m_bufferCharacters8;
313 return m_bufferCharacters8;
314 } 291 }
315 292
316 template <> 293 template <>
317 ALWAYS_INLINE UChar* StringBuilder::getBufferCharacters<UChar>() 294 ALWAYS_INLINE UChar* StringBuilder::getBufferCharacters<UChar>() {
318 { 295 ASSERT(!m_is8Bit);
319 ASSERT(!m_is8Bit); 296 return m_bufferCharacters16;
320 return m_bufferCharacters16;
321 } 297 }
322 298
323 template <typename CharType> 299 template <typename CharType>
324 bool equal(const StringBuilder& s, const CharType* buffer, unsigned length) 300 bool equal(const StringBuilder& s, const CharType* buffer, unsigned length) {
325 { 301 if (s.length() != length)
326 if (s.length() != length) 302 return false;
327 return false; 303
328 304 if (s.is8Bit())
329 if (s.is8Bit()) 305 return equal(s.characters8(), buffer, length);
330 return equal(s.characters8(), buffer, length); 306
331 307 return equal(s.characters16(), buffer, length);
332 return equal(s.characters16(), buffer, length); 308 }
333 } 309
334 310 template <typename CharType>
335 template<typename CharType> 311 bool equalIgnoringCase(const StringBuilder& s, const CharType* buffer, unsigned length) {
336 bool equalIgnoringCase(const StringBuilder& s, const CharType* buffer, unsigned length) 312 if (s.length() != length)
337 { 313 return false;
338 if (s.length() != length) 314
339 return false; 315 if (s.is8Bit())
340 316 return equalIgnoringCase(s.characters8(), buffer, length);
341 if (s.is8Bit()) 317
342 return equalIgnoringCase(s.characters8(), buffer, length); 318 return equalIgnoringCase(s.characters16(), buffer, length);
343 319 }
344 return equalIgnoringCase(s.characters16(), buffer, length); 320
345 } 321 inline bool equalIgnoringCase(const StringBuilder& s, const char* string) {
346 322 return equalIgnoringCase(s, reinterpret_cast<const LChar*>(string), strlen(str ing));
347 inline bool equalIgnoringCase(const StringBuilder& s, const char* string)
348 {
349 return equalIgnoringCase(s, reinterpret_cast<const LChar*>(string), strlen(s tring));
350 } 323 }
351 324
352 template <typename StringType> 325 template <typename StringType>
353 bool equal(const StringBuilder& a, const StringType& b) 326 bool equal(const StringBuilder& a, const StringType& b) {
354 { 327 if (a.length() != b.length())
355 if (a.length() != b.length()) 328 return false;
356 return false; 329
357 330 if (!a.length())
358 if (!a.length()) 331 return true;
359 return true; 332
360 333 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()) 334 if (b.is8Bit())
368 return equal(a.characters16(), b.characters8(), a.length()); 335 return equal(a.characters8(), b.characters8(), a.length());
369 return equal(a.characters16(), b.characters16(), a.length()); 336 return equal(a.characters8(), b.characters16(), a.length());
337 }
338
339 if (b.is8Bit())
340 return equal(a.characters16(), b.characters8(), a.length());
341 return equal(a.characters16(), b.characters16(), a.length());
370 } 342 }
371 343
372 template <typename StringType> 344 template <typename StringType>
373 bool equalIgnoringCase(const StringBuilder& a, const StringType& b) 345 bool equalIgnoringCase(const StringBuilder& a, const StringType& b) {
374 { 346 if (a.length() != b.length())
375 if (a.length() != b.length()) 347 return false;
376 return false; 348
377 349 if (!a.length())
378 if (!a.length()) 350 return true;
379 return true; 351
380 352 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()) 353 if (b.is8Bit())
388 return equalIgnoringCase(a.characters16(), b.characters8(), a.length()); 354 return equalIgnoringCase(a.characters8(), b.characters8(), a.length());
389 return equalIgnoringCase(a.characters16(), b.characters16(), a.length()); 355 return equalIgnoringCase(a.characters8(), b.characters16(), a.length());
390 } 356 }
391 357
392 inline bool operator==(const StringBuilder& a, const StringBuilder& b) { return equal(a, b); } 358 if (b.is8Bit())
393 inline bool operator!=(const StringBuilder& a, const StringBuilder& b) { return !equal(a, b); } 359 return equalIgnoringCase(a.characters16(), b.characters8(), a.length());
394 inline bool operator==(const StringBuilder& a, const String& b) { return equal(a , b); } 360 return equalIgnoringCase(a.characters16(), b.characters16(), a.length());
395 inline bool operator!=(const StringBuilder& a, const String& b) { return !equal( a, b); } 361 }
396 inline bool operator==(const String& a, const StringBuilder& b) { return equal(b , a); } 362
397 inline bool operator!=(const String& a, const StringBuilder& b) { return !equal( b, a); } 363 inline bool operator==(const StringBuilder& a, const StringBuilder& b) {
398 364 return equal(a, b);
399 } // namespace WTF 365 }
366 inline bool operator!=(const StringBuilder& a, const StringBuilder& b) {
367 return !equal(a, b);
368 }
369 inline bool operator==(const StringBuilder& a, const String& b) {
370 return equal(a, b);
371 }
372 inline bool operator!=(const StringBuilder& a, const String& b) {
373 return !equal(a, b);
374 }
375 inline bool operator==(const String& a, const StringBuilder& b) {
376 return equal(b, a);
377 }
378 inline bool operator!=(const String& a, const StringBuilder& b) {
379 return !equal(b, a);
380 }
381
382 } // namespace WTF
400 383
401 using WTF::StringBuilder; 384 using WTF::StringBuilder;
402 385
403 #endif // StringBuilder_h 386 #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