OLD | NEW |
---|---|
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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 { | 95 { |
96 if (!hasBuffer()) | 96 if (!hasBuffer()) |
97 return 0; | 97 return 0; |
98 if (m_is8Bit) | 98 if (m_is8Bit) |
99 return m_buffer8->capacity(); | 99 return m_buffer8->capacity(); |
100 return m_buffer16->capacity(); | 100 return m_buffer16->capacity(); |
101 } | 101 } |
102 | 102 |
103 void StringBuilder::reserveCapacity(unsigned newCapacity) | 103 void StringBuilder::reserveCapacity(unsigned newCapacity) |
104 { | 104 { |
105 if (m_is8Bit) { | 105 if (m_is8Bit) |
106 ensureBuffer8(); | 106 ensureBuffer8(newCapacity); |
107 m_buffer8->reserveCapacity(newCapacity); | 107 else |
108 } else { | 108 ensureBuffer16(newCapacity); |
109 ensureBuffer16(); | |
110 m_buffer16->reserveCapacity(newCapacity); | |
111 } | |
112 } | 109 } |
113 | 110 |
114 void StringBuilder::resize(unsigned newSize) | 111 void StringBuilder::resize(unsigned newSize) |
115 { | 112 { |
116 DCHECK_LE(newSize, m_length); | 113 DCHECK_LE(newSize, m_length); |
117 m_length = newSize; | 114 m_length = newSize; |
118 m_string = String(); | 115 m_string = String(); |
119 if (!hasBuffer()) | 116 if (!hasBuffer()) |
120 return; | 117 return; |
121 if (m_is8Bit) | 118 if (m_is8Bit) |
122 m_buffer8->resize(newSize); | 119 m_buffer8->resize(newSize); |
123 else | 120 else |
124 m_buffer16->resize(newSize); | 121 m_buffer16->resize(newSize); |
125 } | 122 } |
126 | 123 |
127 void StringBuilder::createBuffer8() | 124 void StringBuilder::createBuffer8(unsigned addedSize) |
128 { | 125 { |
129 DCHECK(!hasBuffer()); | 126 DCHECK(!hasBuffer()); |
130 DCHECK(m_is8Bit); | 127 DCHECK(m_is8Bit); |
131 m_buffer8 = new Buffer8; | 128 m_buffer8 = new Buffer8; |
129 // createBuffer is called right before appending addedSize more bytes. We | |
130 // want to ensure we have enough space to fit m_string plus the added | |
131 // size. | |
132 // | |
133 // We also ensure that we have at least the initialBufferSize of extra space | |
134 // for appending new bytes to avoid future mallocs for appending short | |
135 // strings or single characters. This is a no-op if m_length == 0 since | |
136 // initialBufferSize() is the same as the inline capacity of the vector. | |
137 // This allows doing append(string); append('\0') without extra mallocs. | |
138 m_buffer8->reserveInitialCapacity(m_length + std::max(addedSize, initialBuff erSize())); | |
haraken
2016/07/01 02:01:03
I don't quite see any reason you want to take std:
| |
132 m_length = 0; | 139 m_length = 0; |
133 // Must keep a ref to the string since append will clear it. | 140 // Must keep a ref to the string since append will clear it. |
134 String string(m_string); | 141 String string(m_string); |
135 append(string); | 142 append(string); |
136 } | 143 } |
137 | 144 |
138 void StringBuilder::createBuffer16() | 145 void StringBuilder::createBuffer16(unsigned addedSize) |
139 { | 146 { |
140 DCHECK(m_is8Bit || !hasBuffer()); | 147 DCHECK(m_is8Bit || !hasBuffer()); |
141 Buffer8 buffer8; | 148 Buffer8 buffer8; |
142 unsigned length = m_length; | 149 unsigned length = m_length; |
143 if (m_buffer8) { | 150 if (m_buffer8) { |
144 m_buffer8->swap(buffer8); | 151 m_buffer8->swap(buffer8); |
145 delete m_buffer8; | 152 delete m_buffer8; |
146 } | 153 } |
147 m_buffer16 = new Buffer16; | 154 m_buffer16 = new Buffer16; |
155 // See createBuffer8's call to reserveInitialCapacity for why we do this. | |
156 m_buffer16->reserveInitialCapacity(m_length + std::max(addedSize, initialBuf ferSize())); | |
148 m_is8Bit = false; | 157 m_is8Bit = false; |
149 m_length = 0; | 158 m_length = 0; |
150 if (!buffer8.isEmpty()) { | 159 if (!buffer8.isEmpty()) { |
151 append(buffer8.data(), length); | 160 append(buffer8.data(), length); |
152 return; | 161 return; |
153 } | 162 } |
154 // Must keep a ref to the string since append will clear it. | 163 // Must keep a ref to the string since append will clear it. |
155 String string(m_string); | 164 String string(m_string); |
156 append(string); | 165 append(string); |
157 } | 166 } |
158 | 167 |
159 void StringBuilder::append(const UChar* characters, unsigned length) | 168 void StringBuilder::append(const UChar* characters, unsigned length) |
160 { | 169 { |
161 if (!length) | 170 if (!length) |
162 return; | 171 return; |
163 DCHECK(characters); | 172 DCHECK(characters); |
164 | 173 |
165 // If there's only one char we use append(UChar) instead since it will | 174 // If there's only one char we use append(UChar) instead since it will |
166 // check for latin1 and avoid converting to 16bit if possible. | 175 // check for latin1 and avoid converting to 16bit if possible. |
167 if (length == 1) { | 176 if (length == 1) { |
168 append(*characters); | 177 append(*characters); |
169 return; | 178 return; |
170 } | 179 } |
171 | 180 |
172 ensureBuffer16(); | 181 ensureBuffer16(length); |
173 m_string = String(); | 182 m_string = String(); |
174 m_buffer16->append(characters, length); | 183 m_buffer16->append(characters, length); |
175 m_length += length; | 184 m_length += length; |
176 } | 185 } |
177 | 186 |
178 void StringBuilder::append(const LChar* characters, unsigned length) | 187 void StringBuilder::append(const LChar* characters, unsigned length) |
179 { | 188 { |
180 if (!length) | 189 if (!length) |
181 return; | 190 return; |
182 DCHECK(characters); | 191 DCHECK(characters); |
183 | 192 |
184 if (m_is8Bit) { | 193 if (m_is8Bit) { |
185 ensureBuffer8(); | 194 ensureBuffer8(length); |
186 m_string = String(); | 195 m_string = String(); |
187 m_buffer8->append(characters, length); | 196 m_buffer8->append(characters, length); |
188 m_length += length; | 197 m_length += length; |
189 return; | 198 return; |
190 } | 199 } |
191 | 200 |
192 ensureBuffer16(); | 201 ensureBuffer16(length); |
193 m_string = String(); | 202 m_string = String(); |
194 m_buffer16->reserveCapacity(m_buffer16->size() + length); | 203 m_buffer16->reserveCapacity(m_buffer16->size() + length); |
195 for (size_t i = 0; i < length; ++i) | 204 for (size_t i = 0; i < length; ++i) |
196 m_buffer16->uncheckedAppend(characters[i]); | 205 m_buffer16->uncheckedAppend(characters[i]); |
197 m_length += length; | 206 m_length += length; |
198 } | 207 } |
199 | 208 |
200 template<typename IntegerType> | 209 template<typename IntegerType> |
201 static void appendIntegerInternal(StringBuilder& builder, IntegerType input) | 210 static void appendIntegerInternal(StringBuilder& builder, IntegerType input) |
202 { | 211 { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
234 appendIntegerInternal(*this, number); | 243 appendIntegerInternal(*this, number); |
235 } | 244 } |
236 | 245 |
237 void StringBuilder::appendNumber(double number, unsigned precision, TrailingZero sTruncatingPolicy trailingZerosTruncatingPolicy) | 246 void StringBuilder::appendNumber(double number, unsigned precision, TrailingZero sTruncatingPolicy trailingZerosTruncatingPolicy) |
238 { | 247 { |
239 NumberToStringBuffer buffer; | 248 NumberToStringBuffer buffer; |
240 append(numberToFixedPrecisionString(number, precision, buffer, trailingZeros TruncatingPolicy == TruncateTrailingZeros)); | 249 append(numberToFixedPrecisionString(number, precision, buffer, trailingZeros TruncatingPolicy == TruncateTrailingZeros)); |
241 } | 250 } |
242 | 251 |
243 } // namespace WTF | 252 } // namespace WTF |
OLD | NEW |