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

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