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

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

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) 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2010 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 15 matching lines...) Expand all
26 26
27 #include "wtf/text/StringBuilder.h" 27 #include "wtf/text/StringBuilder.h"
28 28
29 #include "wtf/dtoa.h" 29 #include "wtf/dtoa.h"
30 #include "wtf/text/IntegerToStringConversion.h" 30 #include "wtf/text/IntegerToStringConversion.h"
31 #include "wtf/text/WTFString.h" 31 #include "wtf/text/WTFString.h"
32 #include <algorithm> 32 #include <algorithm>
33 33
34 namespace WTF { 34 namespace WTF {
35 35
36 static unsigned expandedCapacity(unsigned capacity, unsigned requiredLength) 36 static unsigned expandedCapacity(unsigned capacity, unsigned requiredLength) {
37 { 37 static const unsigned minimumCapacity = 16;
38 static const unsigned minimumCapacity = 16; 38 return std::max(requiredLength, std::max(minimumCapacity, capacity * 2));
39 return std::max(requiredLength, std::max(minimumCapacity, capacity * 2)); 39 }
40 } 40
41 41 void StringBuilder::reifyString() {
42 void StringBuilder::reifyString() 42 if (!m_string.isNull()) {
43 { 43 ASSERT(m_string.length() == m_length);
44 if (!m_string.isNull()) { 44 return;
45 ASSERT(m_string.length() == m_length); 45 }
46 return; 46
47 } 47 if (!m_length) {
48 48 m_string = StringImpl::empty();
49 if (!m_length) { 49 return;
50 m_string = StringImpl::empty(); 50 }
51 return; 51
52 } 52 ASSERT(m_buffer && m_length <= m_buffer->length());
53 53 if (m_length == m_buffer->length()) {
54 ASSERT(m_buffer && m_length <= m_buffer->length()); 54 m_string = m_buffer.release();
55 if (m_length == m_buffer->length()) { 55 return;
56 m_string = m_buffer.release(); 56 }
57 return; 57
58 } 58 m_string = m_buffer->substring(0, m_length);
59 59 }
60 m_string = m_buffer->substring(0, m_length); 60
61 } 61 String StringBuilder::reifySubstring(unsigned position, unsigned length) const {
62 62 ASSERT(m_string.isNull());
63 String StringBuilder::reifySubstring(unsigned position, unsigned length) const 63 ASSERT(m_buffer);
64 { 64 unsigned substringLength = std::min(length, m_length - position);
65 ASSERT(m_string.isNull()); 65 return m_buffer->substring(position, substringLength);
66 ASSERT(m_buffer); 66 }
67 unsigned substringLength = std::min(length, m_length - position); 67
68 return m_buffer->substring(position, substringLength); 68 void StringBuilder::resize(unsigned newSize) {
69 } 69 // Check newSize < m_length, hence m_length > 0.
70 70 ASSERT(newSize <= m_length);
71 void StringBuilder::resize(unsigned newSize) 71 if (newSize == m_length)
72 { 72 return;
73 // Check newSize < m_length, hence m_length > 0. 73 ASSERT(m_length);
74 ASSERT(newSize <= m_length); 74
75 if (newSize == m_length) 75 // If there is a buffer, we only need to duplicate it if it has more than one ref.
76 return; 76 if (m_buffer) {
77 ASSERT(m_length); 77 m_string =
78 78 String(); // Clear the string to remove the reference to m_buffer if an y before checking the reference count of m_buffer.
79 // If there is a buffer, we only need to duplicate it if it has more than on e ref. 79 if (!m_buffer->hasOneRef()) {
80 if (m_buffer) { 80 if (m_buffer->is8Bit())
81 m_string = String(); // Clear the string to remove the reference to m_bu ffer if any before checking the reference count of m_buffer. 81 allocateBuffer(m_buffer->characters8(), m_buffer->length());
82 if (!m_buffer->hasOneRef()) { 82 else
83 if (m_buffer->is8Bit()) 83 allocateBuffer(m_buffer->characters16(), m_buffer->length());
84 allocateBuffer(m_buffer->characters8(), m_buffer->length()); 84 }
85 else
86 allocateBuffer(m_buffer->characters16(), m_buffer->length());
87 }
88 m_length = newSize;
89 return;
90 }
91
92 // Since m_length && !m_buffer, the string must be valid in m_string, and m_ string.length() > 0.
93 ASSERT(!m_string.isEmpty());
94 ASSERT(m_length == m_string.length());
95 ASSERT(newSize < m_string.length());
96 m_length = newSize; 85 m_length = newSize;
97 RefPtr<StringImpl> string = m_string.releaseImpl(); 86 return;
98 if (string->hasOneRef()) { 87 }
99 // If we're the only ones with a reference to the string, we can 88
100 // re-purpose the string as m_buffer and continue mutating it. 89 // Since m_length && !m_buffer, the string must be valid in m_string, and m_st ring.length() > 0.
101 m_buffer = string; 90 ASSERT(!m_string.isEmpty());
102 } else { 91 ASSERT(m_length == m_string.length());
103 // Otherwise, we need to make a copy of the string so that we don't 92 ASSERT(newSize < m_string.length());
104 // mutate a String that's held elsewhere. 93 m_length = newSize;
105 m_buffer = string->substring(0, m_length); 94 RefPtr<StringImpl> string = m_string.releaseImpl();
106 } 95 if (string->hasOneRef()) {
96 // If we're the only ones with a reference to the string, we can
97 // re-purpose the string as m_buffer and continue mutating it.
98 m_buffer = string;
99 } else {
100 // Otherwise, we need to make a copy of the string so that we don't
101 // mutate a String that's held elsewhere.
102 m_buffer = string->substring(0, m_length);
103 }
107 } 104 }
108 105
109 // Allocate a new 8 bit buffer, copying in currentCharacters (these may come fro m either m_string 106 // Allocate a new 8 bit buffer, copying in currentCharacters (these may come fro m either m_string
110 // or m_buffer, neither will be reassigned until the copy has completed). 107 // or m_buffer, neither will be reassigned until the copy has completed).
111 void StringBuilder::allocateBuffer(const LChar* currentCharacters, unsigned requ iredLength) 108 void StringBuilder::allocateBuffer(const LChar* currentCharacters,
112 { 109 unsigned requiredLength) {
113 ASSERT(m_is8Bit); 110 ASSERT(m_is8Bit);
114 // Copy the existing data into a new buffer, set result to point to the end of the existing data. 111 // Copy the existing data into a new buffer, set result to point to the end of the existing data.
115 RefPtr<StringImpl> buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters8); 112 RefPtr<StringImpl> buffer =
116 memcpy(m_bufferCharacters8, currentCharacters, static_cast<size_t>(m_length) * sizeof(LChar)); // This can't overflow. 113 StringImpl::createUninitialized(requiredLength, m_bufferCharacters8);
117 114 memcpy(
118 // Update the builder state. 115 m_bufferCharacters8, currentCharacters,
119 m_buffer = buffer.release(); 116 static_cast<size_t>(m_length) * sizeof(LChar)); // This can't overflow.
120 m_string = String(); 117
118 // Update the builder state.
119 m_buffer = buffer.release();
120 m_string = String();
121 } 121 }
122 122
123 // Allocate a new 16 bit buffer, copying in currentCharacters (these may come fr om either m_string 123 // Allocate a new 16 bit buffer, copying in currentCharacters (these may come fr om either m_string
124 // or m_buffer, neither will be reassigned until the copy has completed). 124 // or m_buffer, neither will be reassigned until the copy has completed).
125 void StringBuilder::allocateBuffer(const UChar* currentCharacters, unsigned requ iredLength) 125 void StringBuilder::allocateBuffer(const UChar* currentCharacters,
126 { 126 unsigned requiredLength) {
127 ASSERT(!m_is8Bit); 127 ASSERT(!m_is8Bit);
128 // Copy the existing data into a new buffer, set result to point to the end of the existing data. 128 // Copy the existing data into a new buffer, set result to point to the end of the existing data.
129 RefPtr<StringImpl> buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters16); 129 RefPtr<StringImpl> buffer =
130 memcpy(m_bufferCharacters16, currentCharacters, static_cast<size_t>(m_length ) * sizeof(UChar)); // This can't overflow. 130 StringImpl::createUninitialized(requiredLength, m_bufferCharacters16);
131 131 memcpy(
132 // Update the builder state. 132 m_bufferCharacters16, currentCharacters,
133 m_buffer = buffer.release(); 133 static_cast<size_t>(m_length) * sizeof(UChar)); // This can't overflow.
134 m_string = String(); 134
135 // Update the builder state.
136 m_buffer = buffer.release();
137 m_string = String();
135 } 138 }
136 139
137 // Allocate a new 16 bit buffer, copying in currentCharacters (which is 8 bit an d may come 140 // Allocate a new 16 bit buffer, copying in currentCharacters (which is 8 bit an d may come
138 // from either m_string or m_buffer, neither will be reassigned until the copy h as completed). 141 // from either m_string or m_buffer, neither will be reassigned until the copy h as completed).
139 void StringBuilder::allocateBufferUpConvert(const LChar* currentCharacters, unsi gned requiredLength) 142 void StringBuilder::allocateBufferUpConvert(const LChar* currentCharacters,
140 { 143 unsigned requiredLength) {
141 ASSERT(m_is8Bit); 144 ASSERT(m_is8Bit);
142 // Copy the existing data into a new buffer, set result to point to the end of the existing data. 145 // Copy the existing data into a new buffer, set result to point to the end of the existing data.
143 RefPtr<StringImpl> buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters16); 146 RefPtr<StringImpl> buffer =
144 for (unsigned i = 0; i < m_length; ++i) 147 StringImpl::createUninitialized(requiredLength, m_bufferCharacters16);
145 m_bufferCharacters16[i] = currentCharacters[i]; 148 for (unsigned i = 0; i < m_length; ++i)
146 149 m_bufferCharacters16[i] = currentCharacters[i];
147 m_is8Bit = false; 150
148 151 m_is8Bit = false;
149 // Update the builder state. 152
150 m_buffer = buffer.release(); 153 // Update the builder state.
151 m_string = String(); 154 m_buffer = buffer.release();
155 m_string = String();
152 } 156 }
153 157
154 template <> 158 template <>
155 void StringBuilder::reallocateBuffer<LChar>(unsigned requiredLength) 159 void StringBuilder::reallocateBuffer<LChar>(unsigned requiredLength) {
156 { 160 // If the buffer has only one ref (by this StringBuilder), reallocate it,
157 // If the buffer has only one ref (by this StringBuilder), reallocate it, 161 // otherwise fall back to "allocate and copy" method.
158 // otherwise fall back to "allocate and copy" method. 162 m_string = String();
159 m_string = String(); 163
160 164 ASSERT(m_is8Bit);
161 ASSERT(m_is8Bit); 165 ASSERT(m_buffer->is8Bit());
162 ASSERT(m_buffer->is8Bit()); 166
163 167 allocateBuffer(m_buffer->characters8(), requiredLength);
164 allocateBuffer(m_buffer->characters8(), requiredLength);
165 } 168 }
166 169
167 template <> 170 template <>
168 void StringBuilder::reallocateBuffer<UChar>(unsigned requiredLength) 171 void StringBuilder::reallocateBuffer<UChar>(unsigned requiredLength) {
169 { 172 // If the buffer has only one ref (by this StringBuilder), reallocate it,
170 // If the buffer has only one ref (by this StringBuilder), reallocate it, 173 // otherwise fall back to "allocate and copy" method.
171 // otherwise fall back to "allocate and copy" method. 174 m_string = String();
172 m_string = String(); 175
173 176 if (m_buffer->is8Bit())
174 if (m_buffer->is8Bit()) 177 allocateBufferUpConvert(m_buffer->characters8(), requiredLength);
175 allocateBufferUpConvert(m_buffer->characters8(), requiredLength); 178 else
176 else 179 allocateBuffer(m_buffer->characters16(), requiredLength);
177 allocateBuffer(m_buffer->characters16(), requiredLength); 180 }
178 } 181
179 182 void StringBuilder::reserveCapacity(unsigned newCapacity) {
180 void StringBuilder::reserveCapacity(unsigned newCapacity) 183 if (m_buffer) {
181 { 184 // If there is already a buffer, then grow if necessary.
182 if (m_buffer) { 185 if (newCapacity > m_buffer->length()) {
183 // If there is already a buffer, then grow if necessary. 186 if (m_buffer->is8Bit())
184 if (newCapacity > m_buffer->length()) { 187 reallocateBuffer<LChar>(newCapacity);
185 if (m_buffer->is8Bit()) 188 else
186 reallocateBuffer<LChar>(newCapacity); 189 reallocateBuffer<UChar>(newCapacity);
187 else 190 }
188 reallocateBuffer<UChar>(newCapacity); 191 } else {
189 } 192 // Grow the string, if necessary.
190 } else { 193 if (newCapacity > m_length) {
191 // Grow the string, if necessary. 194 if (!m_length) {
192 if (newCapacity > m_length) { 195 LChar* nullPlaceholder = 0;
193 if (!m_length) { 196 allocateBuffer(nullPlaceholder, newCapacity);
194 LChar* nullPlaceholder = 0; 197 } else if (m_string.is8Bit()) {
195 allocateBuffer(nullPlaceholder, newCapacity); 198 allocateBuffer(m_string.characters8(), newCapacity);
196 } else if (m_string.is8Bit()) { 199 } else {
197 allocateBuffer(m_string.characters8(), newCapacity); 200 allocateBuffer(m_string.characters16(), newCapacity);
198 } else { 201 }
199 allocateBuffer(m_string.characters16(), newCapacity); 202 }
200 } 203 }
201 }
202 }
203 } 204 }
204 205
205 // Make 'length' additional capacity be available in m_buffer, update m_string & m_length, 206 // Make 'length' additional capacity be available in m_buffer, update m_string & m_length,
206 // return a pointer to the newly allocated storage. 207 // return a pointer to the newly allocated storage.
207 template <typename CharType> 208 template <typename CharType>
208 ALWAYS_INLINE CharType* StringBuilder::appendUninitialized(unsigned length) 209 ALWAYS_INLINE CharType* StringBuilder::appendUninitialized(unsigned length) {
209 { 210 ASSERT(length);
210 ASSERT(length); 211
212 // Calculate the new size of the builder after appending.
213 unsigned requiredLength = length + m_length;
214 RELEASE_ASSERT(requiredLength >= length);
215
216 if ((m_buffer) && (requiredLength <= m_buffer->length())) {
217 // If the buffer is valid it must be at least as long as the current builder contents!
218 ASSERT(m_buffer->length() >= m_length);
219 unsigned currentLength = m_length;
220 m_string = String();
221 m_length = requiredLength;
222 return getBufferCharacters<CharType>() + currentLength;
223 }
224
225 return appendUninitializedSlow<CharType>(requiredLength);
226 }
227
228 // Make 'length' additional capacity be available in m_buffer, update m_string & m_length,
229 // return a pointer to the newly allocated storage.
230 template <typename CharType>
231 CharType* StringBuilder::appendUninitializedSlow(unsigned requiredLength) {
232 ASSERT(requiredLength);
233
234 if (m_buffer) {
235 // If the buffer is valid it must be at least as long as the current builder contents!
236 ASSERT(m_buffer->length() >= m_length);
237
238 reallocateBuffer<CharType>(expandedCapacity(capacity(), requiredLength));
239 } else {
240 ASSERT(m_string.length() == m_length);
241 allocateBuffer(m_length ? m_string.getCharacters<CharType>() : 0,
242 expandedCapacity(capacity(), requiredLength));
243 }
244
245 CharType* result = getBufferCharacters<CharType>() + m_length;
246 m_length = requiredLength;
247 return result;
248 }
249
250 void StringBuilder::append(const UChar* characters, unsigned length) {
251 if (!length)
252 return;
253
254 ASSERT(characters);
255
256 if (m_is8Bit) {
257 if (length == 1 && !(*characters & ~0xff)) {
258 // Append as 8 bit character
259 LChar lChar = static_cast<LChar>(*characters);
260 append(&lChar, 1);
261 return;
262 }
211 263
212 // Calculate the new size of the builder after appending. 264 // Calculate the new size of the builder after appending.
213 unsigned requiredLength = length + m_length; 265 unsigned requiredLength = length + m_length;
214 RELEASE_ASSERT(requiredLength >= length); 266 RELEASE_ASSERT(requiredLength >= length);
215 267
216 if ((m_buffer) && (requiredLength <= m_buffer->length())) {
217 // If the buffer is valid it must be at least as long as the current bui lder contents!
218 ASSERT(m_buffer->length() >= m_length);
219 unsigned currentLength = m_length;
220 m_string = String();
221 m_length = requiredLength;
222 return getBufferCharacters<CharType>() + currentLength;
223 }
224
225 return appendUninitializedSlow<CharType>(requiredLength);
226 }
227
228 // Make 'length' additional capacity be available in m_buffer, update m_string & m_length,
229 // return a pointer to the newly allocated storage.
230 template <typename CharType>
231 CharType* StringBuilder::appendUninitializedSlow(unsigned requiredLength)
232 {
233 ASSERT(requiredLength);
234
235 if (m_buffer) { 268 if (m_buffer) {
236 // If the buffer is valid it must be at least as long as the current bui lder contents! 269 // If the buffer is valid it must be at least as long as the current build er contents!
237 ASSERT(m_buffer->length() >= m_length); 270 ASSERT(m_buffer->length() >= m_length);
238 271
239 reallocateBuffer<CharType>(expandedCapacity(capacity(), requiredLength)) ; 272 allocateBufferUpConvert(m_buffer->characters8(),
273 expandedCapacity(capacity(), requiredLength));
240 } else { 274 } else {
241 ASSERT(m_string.length() == m_length); 275 ASSERT(m_string.length() == m_length);
242 allocateBuffer(m_length ? m_string.getCharacters<CharType>() : 0, expand edCapacity(capacity(), requiredLength)); 276 allocateBufferUpConvert(m_string.isNull() ? 0 : m_string.characters8(),
243 } 277 expandedCapacity(capacity(), requiredLength));
244 278 }
245 CharType* result = getBufferCharacters<CharType>() + m_length; 279
280 memcpy(m_bufferCharacters16 + m_length, characters,
281 static_cast<size_t>(length) * sizeof(UChar));
246 m_length = requiredLength; 282 m_length = requiredLength;
247 return result; 283 } else {
248 } 284 memcpy(appendUninitialized<UChar>(length), characters,
249 285 static_cast<size_t>(length) * sizeof(UChar));
250 void StringBuilder::append(const UChar* characters, unsigned length) 286 }
251 { 287 }
252 if (!length) 288
253 return; 289 void StringBuilder::append(const LChar* characters, unsigned length) {
254 290 if (!length)
255 ASSERT(characters); 291 return;
256 292 ASSERT(characters);
257 if (m_is8Bit) { 293
258 if (length == 1 && !(*characters & ~0xff)) { 294 if (m_is8Bit) {
259 // Append as 8 bit character 295 LChar* dest = appendUninitialized<LChar>(length);
260 LChar lChar = static_cast<LChar>(*characters); 296 if (length > 8) {
261 append(&lChar, 1); 297 memcpy(dest, characters, static_cast<size_t>(length) * sizeof(LChar));
262 return;
263 }
264
265 // Calculate the new size of the builder after appending.
266 unsigned requiredLength = length + m_length;
267 RELEASE_ASSERT(requiredLength >= length);
268
269 if (m_buffer) {
270 // If the buffer is valid it must be at least as long as the current builder contents!
271 ASSERT(m_buffer->length() >= m_length);
272
273 allocateBufferUpConvert(m_buffer->characters8(), expandedCapacity(ca pacity(), requiredLength));
274 } else {
275 ASSERT(m_string.length() == m_length);
276 allocateBufferUpConvert(m_string.isNull() ? 0 : m_string.characters8 (), expandedCapacity(capacity(), requiredLength));
277 }
278
279 memcpy(m_bufferCharacters16 + m_length, characters, static_cast<size_t>( length) * sizeof(UChar));
280 m_length = requiredLength;
281 } else { 298 } else {
282 memcpy(appendUninitialized<UChar>(length), characters, static_cast<size_ t>(length) * sizeof(UChar)); 299 const LChar* end = characters + length;
283 } 300 while (characters < end)
284 } 301 *(dest++) = *(characters++);
285 302 }
286 void StringBuilder::append(const LChar* characters, unsigned length) 303 } else {
287 { 304 UChar* dest = appendUninitialized<UChar>(length);
288 if (!length) 305 const LChar* end = characters + length;
289 return; 306 while (characters < end)
290 ASSERT(characters); 307 *(dest++) = *(characters++);
291 308 }
292 if (m_is8Bit) { 309 }
293 LChar* dest = appendUninitialized<LChar>(length); 310
294 if (length > 8) { 311 void StringBuilder::appendNumber(int number) {
295 memcpy(dest, characters, static_cast<size_t>(length) * sizeof(LChar) ); 312 numberToStringSigned<StringBuilder>(number, this);
296 } else { 313 }
297 const LChar* end = characters + length; 314
298 while (characters < end) 315 void StringBuilder::appendNumber(unsigned number) {
299 *(dest++) = *(characters++); 316 numberToStringUnsigned<StringBuilder>(number, this);
300 } 317 }
301 } else { 318
302 UChar* dest = appendUninitialized<UChar>(length); 319 void StringBuilder::appendNumber(long number) {
303 const LChar* end = characters + length; 320 numberToStringSigned<StringBuilder>(number, this);
304 while (characters < end) 321 }
305 *(dest++) = *(characters++); 322
306 } 323 void StringBuilder::appendNumber(unsigned long number) {
307 } 324 numberToStringUnsigned<StringBuilder>(number, this);
308 325 }
309 void StringBuilder::appendNumber(int number) 326
310 { 327 void StringBuilder::appendNumber(long long number) {
311 numberToStringSigned<StringBuilder>(number, this); 328 numberToStringSigned<StringBuilder>(number, this);
312 } 329 }
313 330
314 void StringBuilder::appendNumber(unsigned number) 331 void StringBuilder::appendNumber(unsigned long long number) {
315 { 332 numberToStringUnsigned<StringBuilder>(number, this);
316 numberToStringUnsigned<StringBuilder>(number, this); 333 }
317 } 334
318 335 static void expandLCharToUCharInplace(UChar* buffer, size_t length) {
319 void StringBuilder::appendNumber(long number) 336 const LChar* sourceEnd = reinterpret_cast<LChar*>(buffer) + length;
320 { 337 UChar* current = buffer + length;
321 numberToStringSigned<StringBuilder>(number, this); 338 while (current != buffer)
322 } 339 *--current = *--sourceEnd;
323 340 }
324 void StringBuilder::appendNumber(unsigned long number) 341
325 { 342 void StringBuilder::appendNumber(
326 numberToStringUnsigned<StringBuilder>(number, this); 343 double number,
327 } 344 unsigned precision,
328 345 TrailingZerosTruncatingPolicy trailingZerosTruncatingPolicy) {
329 void StringBuilder::appendNumber(long long number) 346 bool truncateTrailingZeros =
330 { 347 trailingZerosTruncatingPolicy == TruncateTrailingZeros;
331 numberToStringSigned<StringBuilder>(number, this); 348 size_t numberLength;
332 } 349 if (m_is8Bit) {
333 350 LChar* dest = appendUninitialized<LChar>(NumberToStringBufferLength);
334 void StringBuilder::appendNumber(unsigned long long number) 351 const char* result = numberToFixedPrecisionString(
335 { 352 number, precision, reinterpret_cast<char*>(dest),
336 numberToStringUnsigned<StringBuilder>(number, this); 353 truncateTrailingZeros);
337 } 354 numberLength = strlen(result);
338 355 } else {
339 static void expandLCharToUCharInplace(UChar* buffer, size_t length) 356 UChar* dest = appendUninitialized<UChar>(NumberToStringBufferLength);
340 { 357 const char* result = numberToFixedPrecisionString(
341 const LChar* sourceEnd = reinterpret_cast<LChar*>(buffer) + length; 358 number, precision, reinterpret_cast<char*>(dest),
342 UChar* current = buffer + length; 359 truncateTrailingZeros);
343 while (current != buffer) 360 numberLength = strlen(result);
344 *--current = *--sourceEnd; 361 expandLCharToUCharInplace(dest, numberLength);
345 } 362 }
346 363 ASSERT(m_length >= NumberToStringBufferLength);
347 void StringBuilder::appendNumber(double number, unsigned precision, TrailingZero sTruncatingPolicy trailingZerosTruncatingPolicy) 364 // Remove what appendUninitialized added.
348 { 365 m_length -= NumberToStringBufferLength;
349 bool truncateTrailingZeros = trailingZerosTruncatingPolicy == TruncateTraili ngZeros; 366 ASSERT(numberLength <= NumberToStringBufferLength);
350 size_t numberLength; 367 m_length += numberLength;
351 if (m_is8Bit) { 368 }
352 LChar* dest = appendUninitialized<LChar>(NumberToStringBufferLength); 369
353 const char* result = numberToFixedPrecisionString(number, precision, rei nterpret_cast<char*>(dest), truncateTrailingZeros); 370 bool StringBuilder::canShrink() const {
354 numberLength = strlen(result); 371 // Only shrink the buffer if it's less than 80% full. Need to tune this heuris tic!
355 } else { 372 return m_buffer && m_buffer->length() > (m_length + (m_length >> 2));
356 UChar* dest = appendUninitialized<UChar>(NumberToStringBufferLength); 373 }
357 const char* result = numberToFixedPrecisionString(number, precision, rei nterpret_cast<char*>(dest), truncateTrailingZeros); 374
358 numberLength = strlen(result); 375 void StringBuilder::shrinkToFit() {
359 expandLCharToUCharInplace(dest, numberLength); 376 if (!canShrink())
360 } 377 return;
361 ASSERT(m_length >= NumberToStringBufferLength); 378 if (m_is8Bit)
362 // Remove what appendUninitialized added. 379 reallocateBuffer<LChar>(m_length);
363 m_length -= NumberToStringBufferLength; 380 else
364 ASSERT(numberLength <= NumberToStringBufferLength); 381 reallocateBuffer<UChar>(m_length);
365 m_length += numberLength; 382 m_string = m_buffer.release();
366 } 383 }
367 384
368 bool StringBuilder::canShrink() const 385 } // namespace WTF
369 {
370 // Only shrink the buffer if it's less than 80% full. Need to tune this heur istic!
371 return m_buffer && m_buffer->length() > (m_length + (m_length >> 2));
372 }
373
374 void StringBuilder::shrinkToFit()
375 {
376 if (!canShrink())
377 return;
378 if (m_is8Bit)
379 reallocateBuffer<LChar>(m_length);
380 else
381 reallocateBuffer<UChar>(m_length);
382 m_string = m_buffer.release();
383 }
384
385 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/StringBuilder.h ('k') | third_party/WebKit/Source/wtf/text/StringBuilderTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698