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

Side by Side Diff: third_party/WebKit/Source/wtf/text/WTFString.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 * (C) 1999 Lars Knoll (knoll@kde.org) 2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc. All rights reserved. 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc. All rights reserved.
4 * Copyright (C) 2007-2009 Torch Mobile, Inc. 4 * Copyright (C) 2007-2009 Torch Mobile, Inc.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 24 matching lines...) Expand all
35 #include "wtf/text/UTF8.h" 35 #include "wtf/text/UTF8.h"
36 #include "wtf/text/Unicode.h" 36 #include "wtf/text/Unicode.h"
37 #include <stdarg.h> 37 #include <stdarg.h>
38 38
39 namespace WTF { 39 namespace WTF {
40 40
41 using namespace Unicode; 41 using namespace Unicode;
42 42
43 // Construct a string with UTF-16 data. 43 // Construct a string with UTF-16 data.
44 String::String(const UChar* characters, unsigned length) 44 String::String(const UChar* characters, unsigned length)
45 : m_impl(characters ? StringImpl::create(characters, length) : nullptr) 45 : m_impl(characters ? StringImpl::create(characters, length) : nullptr) {
46 {
47 } 46 }
48 47
49 // Construct a string with UTF-16 data, from a null-terminated source. 48 // Construct a string with UTF-16 data, from a null-terminated source.
50 String::String(const UChar* str) 49 String::String(const UChar* str) {
51 { 50 if (!str)
52 if (!str) 51 return;
53 return; 52 m_impl = StringImpl::create(str, lengthOfNullTerminatedString(str));
54 m_impl = StringImpl::create(str, lengthOfNullTerminatedString(str));
55 } 53 }
56 54
57 // Construct a string with latin1 data. 55 // Construct a string with latin1 data.
58 String::String(const LChar* characters, unsigned length) 56 String::String(const LChar* characters, unsigned length)
59 : m_impl(characters ? StringImpl::create(characters, length) : nullptr) 57 : m_impl(characters ? StringImpl::create(characters, length) : nullptr) {
60 {
61 } 58 }
62 59
63 String::String(const char* characters, unsigned length) 60 String::String(const char* characters, unsigned length)
64 : m_impl(characters ? StringImpl::create(reinterpret_cast<const LChar*>(char acters), length) : nullptr) 61 : m_impl(characters ? StringImpl::create(reinterpret_cast<const LChar*>(char acters), length) : nullptr) {
65 {
66 } 62 }
67 63
68 // Construct a string with latin1 data, from a null-terminated source. 64 // Construct a string with latin1 data, from a null-terminated source.
69 String::String(const LChar* characters) 65 String::String(const LChar* characters)
70 : m_impl(characters ? StringImpl::create(characters) : nullptr) 66 : m_impl(characters ? StringImpl::create(characters) : nullptr) {
71 {
72 } 67 }
73 68
74 String::String(const char* characters) 69 String::String(const char* characters)
75 : m_impl(characters ? StringImpl::create(reinterpret_cast<const LChar*>(char acters)) : nullptr) 70 : m_impl(characters ? StringImpl::create(reinterpret_cast<const LChar*>(char acters)) : nullptr) {
76 { 71 }
77 } 72
78 73 void String::append(const String& string) {
79 void String::append(const String& string) 74 if (string.isEmpty())
80 { 75 return;
81 if (string.isEmpty()) 76 if (!m_impl) {
82 return; 77 m_impl = string.m_impl;
83 if (!m_impl) { 78 return;
84 m_impl = string.m_impl; 79 }
85 return; 80
86 } 81 // FIXME: This is extremely inefficient. So much so that we might want to
87 82 // take this out of String's API. We can make it better by optimizing the
88 // FIXME: This is extremely inefficient. So much so that we might want to 83 // case where exactly one String is pointing at this StringImpl, but even
89 // take this out of String's API. We can make it better by optimizing the 84 // then it's going to require a call into the allocator every single time.
90 // case where exactly one String is pointing at this StringImpl, but even 85
91 // then it's going to require a call into the allocator every single time. 86 if (m_impl->is8Bit() && string.m_impl->is8Bit()) {
92 87 LChar* data;
93 if (m_impl->is8Bit() && string.m_impl->is8Bit()) {
94 LChar* data;
95 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() - m_impl->length());
96 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->len gth() + string.length(), data);
97 memcpy(data, m_impl->characters8(), m_impl->length() * sizeof(LChar));
98 memcpy(data + m_impl->length(), string.characters8(), string.length() * sizeof(LChar));
99 m_impl = newImpl.release();
100 return;
101 }
102
103 UChar* data;
104 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() - m_i mpl->length()); 88 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() - m_i mpl->length());
105 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length( ) + string.length(), data); 89 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length( ) + string.length(), data);
106 90 memcpy(data, m_impl->characters8(), m_impl->length() * sizeof(LChar));
107 if (m_impl->is8Bit()) 91 memcpy(data + m_impl->length(), string.characters8(), string.length() * size of(LChar));
108 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length());
109 else
110 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length());
111
112 if (string.impl()->is8Bit())
113 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters 8(), string.impl()->length());
114 else
115 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters 16(), string.impl()->length());
116
117 m_impl = newImpl.release(); 92 m_impl = newImpl.release();
93 return;
94 }
95
96 UChar* data;
97 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() - m_imp l->length());
98 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + string.length(), data);
99
100 if (m_impl->is8Bit())
101 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length());
102 else
103 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length());
104
105 if (string.impl()->is8Bit())
106 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters8(), string.impl()->length());
107 else
108 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters16() , string.impl()->length());
109
110 m_impl = newImpl.release();
118 } 111 }
119 112
120 template <typename CharacterType> 113 template <typename CharacterType>
121 inline void String::appendInternal(CharacterType c) 114 inline void String::appendInternal(CharacterType c) {
122 { 115 // FIXME: This is extremely inefficient. So much so that we might want to
123 // FIXME: This is extremely inefficient. So much so that we might want to 116 // take this out of String's API. We can make it better by optimizing the
124 // take this out of String's API. We can make it better by optimizing the 117 // case where exactly one String is pointing at this StringImpl, but even
125 // case where exactly one String is pointing at this StringImpl, but even 118 // then it's going to require a call into the allocator every single time.
126 // then it's going to require a call into the allocator every single time. 119 if (!m_impl) {
127 if (!m_impl) { 120 m_impl = StringImpl::create(&c, 1);
128 m_impl = StringImpl::create(&c, 1); 121 return;
129 return; 122 }
130 } 123
131 124 // FIXME: We should be able to create an 8 bit string via this code path.
132 // FIXME: We should be able to create an 8 bit string via this code path. 125 UChar* data;
133 UChar* data; 126 RELEASE_ASSERT(m_impl->length() < std::numeric_limits<unsigned>::max());
134 RELEASE_ASSERT(m_impl->length() < std::numeric_limits<unsigned>::max()); 127 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + 1, data);
135 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length( ) + 1, data); 128 if (m_impl->is8Bit())
136 if (m_impl->is8Bit()) 129 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length());
137 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length()); 130 else
138 else 131 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length());
139 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); 132 data[m_impl->length()] = c;
140 data[m_impl->length()] = c; 133 m_impl = newImpl.release();
141 m_impl = newImpl.release(); 134 }
142 } 135
143 136 void String::append(LChar c) {
144 void String::append(LChar c) 137 appendInternal(c);
145 { 138 }
146 appendInternal(c); 139
147 } 140 void String::append(UChar c) {
148 141 appendInternal(c);
149 void String::append(UChar c) 142 }
150 { 143
151 appendInternal(c); 144 int codePointCompare(const String& a, const String& b) {
152 } 145 return codePointCompare(a.impl(), b.impl());
153 146 }
154 int codePointCompare(const String& a, const String& b) 147
155 { 148 void String::insert(const String& string, unsigned position) {
156 return codePointCompare(a.impl(), b.impl()); 149 if (string.isEmpty()) {
157 } 150 if (string.isNull())
158 151 return;
159 void String::insert(const String& string, unsigned position) 152 if (isNull())
160 { 153 m_impl = string.impl();
161 if (string.isEmpty()) { 154 return;
162 if (string.isNull()) 155 }
163 return; 156
164 if (isNull()) 157 if (string.is8Bit())
165 m_impl = string.impl(); 158 insert(string.impl()->characters8(), string.length(), position);
166 return; 159 else
167 } 160 insert(string.impl()->characters16(), string.length(), position);
168 161 }
169 if (string.is8Bit()) 162
170 insert(string.impl()->characters8(), string.length(), position); 163 void String::append(const LChar* charactersToAppend, unsigned lengthToAppend) {
171 else 164 if (!m_impl) {
172 insert(string.impl()->characters16(), string.length(), position); 165 if (!charactersToAppend)
173 } 166 return;
174 167 m_impl = StringImpl::create(charactersToAppend, lengthToAppend);
175 void String::append(const LChar* charactersToAppend, unsigned lengthToAppend) 168 return;
176 { 169 }
177 if (!m_impl) { 170
178 if (!charactersToAppend) 171 if (!lengthToAppend)
179 return; 172 return;
180 m_impl = StringImpl::create(charactersToAppend, lengthToAppend); 173
181 return; 174 ASSERT(charactersToAppend);
182 } 175
183 176 unsigned strLength = m_impl->length();
184 if (!lengthToAppend) 177
185 return; 178 if (m_impl->is8Bit()) {
186
187 ASSERT(charactersToAppend);
188
189 unsigned strLength = m_impl->length();
190
191 if (m_impl->is8Bit()) {
192 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strLength);
193 LChar* data;
194 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + lengthToAppend, data);
195 StringImpl::copyChars(data, m_impl->characters8(), strLength);
196 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppe nd);
197 m_impl = newImpl.release();
198 return;
199 }
200
201 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strL ength); 179 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strL ength);
202 UChar* data; 180 LChar* data;
203 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + leng thToAppend, data); 181 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + len gthToAppend, data);
204 StringImpl::copyChars(data, m_impl->characters16(), strLength); 182 StringImpl::copyChars(data, m_impl->characters8(), strLength);
205 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); 183 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
206 m_impl = newImpl.release(); 184 m_impl = newImpl.release();
207 } 185 return;
208 186 }
209 void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) 187
210 { 188 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strLen gth);
211 if (!m_impl) { 189 UChar* data;
212 if (!charactersToAppend) 190 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + length ToAppend, data);
213 return; 191 StringImpl::copyChars(data, m_impl->characters16(), strLength);
214 m_impl = StringImpl::create(charactersToAppend, lengthToAppend); 192 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
215 return; 193 m_impl = newImpl.release();
216 } 194 }
217 195
218 if (!lengthToAppend) 196 void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) {
219 return; 197 if (!m_impl) {
220 198 if (!charactersToAppend)
221 unsigned strLength = m_impl->length(); 199 return;
222 200 m_impl = StringImpl::create(charactersToAppend, lengthToAppend);
223 ASSERT(charactersToAppend); 201 return;
224 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strL ength); 202 }
203
204 if (!lengthToAppend)
205 return;
206
207 unsigned strLength = m_impl->length();
208
209 ASSERT(charactersToAppend);
210 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strLen gth);
211 UChar* data;
212 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + lengt hToAppend, data);
213 if (m_impl->is8Bit())
214 StringImpl::copyChars(data, characters8(), strLength);
215 else
216 StringImpl::copyChars(data, characters16(), strLength);
217 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
218 m_impl = newImpl.release();
219 }
220
221 template <typename CharType>
222 PassRefPtr<StringImpl> insertInternal(PassRefPtr<StringImpl> impl, const CharTyp e* charactersToInsert, unsigned lengthToInsert, unsigned position) {
223 if (!lengthToInsert)
224 return impl;
225
226 ASSERT(charactersToInsert);
227 UChar* data; // FIXME: We should be able to create an 8 bit string here.
228 RELEASE_ASSERT(lengthToInsert <= std::numeric_limits<unsigned>::max() - impl-> length());
229 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(impl->length() + lengthToInsert, data);
230
231 if (impl->is8Bit())
232 StringImpl::copyChars(data, impl->characters8(), position);
233 else
234 StringImpl::copyChars(data, impl->characters16(), position);
235
236 StringImpl::copyChars(data + position, charactersToInsert, lengthToInsert);
237
238 if (impl->is8Bit())
239 StringImpl::copyChars(data + position + lengthToInsert, impl->characters8() + position, impl->length() - position);
240 else
241 StringImpl::copyChars(data + position + lengthToInsert, impl->characters16() + position, impl->length() - position);
242
243 return newImpl.release();
244 }
245
246 void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, un signed position) {
247 if (position >= length()) {
248 append(charactersToInsert, lengthToInsert);
249 return;
250 }
251 ASSERT(m_impl);
252 m_impl = insertInternal(m_impl.release(), charactersToInsert, lengthToInsert, position);
253 }
254
255 void String::insert(const LChar* charactersToInsert, unsigned lengthToInsert, un signed position) {
256 if (position >= length()) {
257 append(charactersToInsert, lengthToInsert);
258 return;
259 }
260 ASSERT(m_impl);
261 m_impl = insertInternal(m_impl.release(), charactersToInsert, lengthToInsert, position);
262 }
263
264 UChar32 String::characterStartingAt(unsigned i) const {
265 if (!m_impl || i >= m_impl->length())
266 return 0;
267 return m_impl->characterStartingAt(i);
268 }
269
270 void String::ensure16Bit() {
271 unsigned length = this->length();
272 if (!length || !is8Bit())
273 return;
274 m_impl = make16BitFrom8BitSource(m_impl->characters8(), length).impl();
275 }
276
277 void String::truncate(unsigned position) {
278 if (position >= length())
279 return;
280 if (m_impl->is8Bit()) {
281 LChar* data;
282 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(position, data) ;
283 memcpy(data, m_impl->characters8(), position * sizeof(LChar));
284 m_impl = newImpl.release();
285 } else {
225 UChar* data; 286 UChar* data;
226 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + len gthToAppend, data); 287 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(position, data) ;
227 if (m_impl->is8Bit()) 288 memcpy(data, m_impl->characters16(), position * sizeof(UChar));
228 StringImpl::copyChars(data, characters8(), strLength);
229 else
230 StringImpl::copyChars(data, characters16(), strLength);
231 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
232 m_impl = newImpl.release(); 289 m_impl = newImpl.release();
233 } 290 }
234
235 template<typename CharType>
236 PassRefPtr<StringImpl> insertInternal(PassRefPtr<StringImpl> impl, const CharTyp e* charactersToInsert, unsigned lengthToInsert, unsigned position)
237 {
238 if (!lengthToInsert)
239 return impl;
240
241 ASSERT(charactersToInsert);
242 UChar* data; // FIXME: We should be able to create an 8 bit string here.
243 RELEASE_ASSERT(lengthToInsert <= std::numeric_limits<unsigned>::max() - impl ->length());
244 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(impl->length() + lengthToInsert, data);
245
246 if (impl->is8Bit())
247 StringImpl::copyChars(data, impl->characters8(), position);
248 else
249 StringImpl::copyChars(data, impl->characters16(), position);
250
251 StringImpl::copyChars(data + position, charactersToInsert, lengthToInsert);
252
253 if (impl->is8Bit())
254 StringImpl::copyChars(data + position + lengthToInsert, impl->characters 8() + position, impl->length() - position);
255 else
256 StringImpl::copyChars(data + position + lengthToInsert, impl->characters 16() + position, impl->length() - position);
257
258 return newImpl.release();
259 }
260
261 void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, un signed position)
262 {
263 if (position >= length()) {
264 append(charactersToInsert, lengthToInsert);
265 return;
266 }
267 ASSERT(m_impl);
268 m_impl = insertInternal(m_impl.release(), charactersToInsert, lengthToInsert , position);
269 }
270
271 void String::insert(const LChar* charactersToInsert, unsigned lengthToInsert, un signed position)
272 {
273 if (position >= length()) {
274 append(charactersToInsert, lengthToInsert);
275 return;
276 }
277 ASSERT(m_impl);
278 m_impl = insertInternal(m_impl.release(), charactersToInsert, lengthToInsert , position);
279 }
280
281 UChar32 String::characterStartingAt(unsigned i) const
282 {
283 if (!m_impl || i >= m_impl->length())
284 return 0;
285 return m_impl->characterStartingAt(i);
286 }
287
288 void String::ensure16Bit()
289 {
290 unsigned length = this->length();
291 if (!length || !is8Bit())
292 return;
293 m_impl = make16BitFrom8BitSource(m_impl->characters8(), length).impl();
294 }
295
296 void String::truncate(unsigned position)
297 {
298 if (position >= length())
299 return;
300 if (m_impl->is8Bit()) {
301 LChar* data;
302 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(position, d ata);
303 memcpy(data, m_impl->characters8(), position * sizeof(LChar));
304 m_impl = newImpl.release();
305 } else {
306 UChar* data;
307 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(position, d ata);
308 memcpy(data, m_impl->characters16(), position * sizeof(UChar));
309 m_impl = newImpl.release();
310 }
311 } 291 }
312 292
313 template <typename CharacterType> 293 template <typename CharacterType>
314 inline void String::removeInternal(const CharacterType* characters, unsigned pos ition, int lengthToRemove) 294 inline void String::removeInternal(const CharacterType* characters, unsigned pos ition, int lengthToRemove) {
315 { 295 CharacterType* data;
316 CharacterType* data; 296 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() - length ToRemove, data);
317 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() - leng thToRemove, data); 297 memcpy(data, characters, position * sizeof(CharacterType));
318 memcpy(data, characters, position * sizeof(CharacterType)); 298 memcpy(data + position, characters + position + lengthToRemove,
319 memcpy(data + position, characters + position + lengthToRemove, 299 (length() - lengthToRemove - position) * sizeof(CharacterType));
320 (length() - lengthToRemove - position) * sizeof(CharacterType)); 300
321 301 m_impl = newImpl.release();
322 m_impl = newImpl.release(); 302 }
323 } 303
324 304 void String::remove(unsigned position, int lengthToRemove) {
325 void String::remove(unsigned position, int lengthToRemove) 305 if (lengthToRemove <= 0)
326 { 306 return;
327 if (lengthToRemove <= 0) 307 if (position >= length())
328 return; 308 return;
329 if (position >= length()) 309 if (static_cast<unsigned>(lengthToRemove) > length() - position)
330 return; 310 lengthToRemove = length() - position;
331 if (static_cast<unsigned>(lengthToRemove) > length() - position) 311
332 lengthToRemove = length() - position; 312 if (is8Bit()) {
333 313 removeInternal(characters8(), position, lengthToRemove);
334 if (is8Bit()) { 314
335 removeInternal(characters8(), position, lengthToRemove); 315 return;
336 316 }
337 return; 317
338 } 318 removeInternal(characters16(), position, lengthToRemove);
339 319 }
340 removeInternal(characters16(), position, lengthToRemove); 320
341 } 321 String String::substring(unsigned pos, unsigned len) const {
342 322 if (!m_impl)
343 String String::substring(unsigned pos, unsigned len) const 323 return String();
344 { 324 return m_impl->substring(pos, len);
345 if (!m_impl) 325 }
346 return String(); 326
347 return m_impl->substring(pos, len); 327 String String::lower() const {
348 } 328 if (!m_impl)
349 329 return String();
350 String String::lower() const 330 return m_impl->lower();
351 { 331 }
352 if (!m_impl) 332
353 return String(); 333 String String::upper() const {
354 return m_impl->lower(); 334 if (!m_impl)
355 } 335 return String();
356 336 return m_impl->upper();
357 String String::upper() const 337 }
358 { 338
359 if (!m_impl) 339 String String::lower(const AtomicString& localeIdentifier) const {
360 return String(); 340 if (!m_impl)
361 return m_impl->upper(); 341 return String();
362 } 342 return m_impl->lower(localeIdentifier);
363 343 }
364 String String::lower(const AtomicString& localeIdentifier) const 344
365 { 345 String String::upper(const AtomicString& localeIdentifier) const {
366 if (!m_impl) 346 if (!m_impl)
367 return String(); 347 return String();
368 return m_impl->lower(localeIdentifier); 348 return m_impl->upper(localeIdentifier);
369 } 349 }
370 350
371 String String::upper(const AtomicString& localeIdentifier) const 351 String String::stripWhiteSpace() const {
372 { 352 if (!m_impl)
373 if (!m_impl) 353 return String();
374 return String(); 354 return m_impl->stripWhiteSpace();
375 return m_impl->upper(localeIdentifier); 355 }
376 } 356
377 357 String String::stripWhiteSpace(IsWhiteSpaceFunctionPtr isWhiteSpace) const {
378 String String::stripWhiteSpace() const 358 if (!m_impl)
379 { 359 return String();
380 if (!m_impl) 360 return m_impl->stripWhiteSpace(isWhiteSpace);
381 return String(); 361 }
382 return m_impl->stripWhiteSpace(); 362
383 } 363 String String::simplifyWhiteSpace(StripBehavior stripBehavior) const {
384 364 if (!m_impl)
385 String String::stripWhiteSpace(IsWhiteSpaceFunctionPtr isWhiteSpace) const 365 return String();
386 { 366 return m_impl->simplifyWhiteSpace(stripBehavior);
387 if (!m_impl) 367 }
388 return String(); 368
389 return m_impl->stripWhiteSpace(isWhiteSpace); 369 String String::simplifyWhiteSpace(IsWhiteSpaceFunctionPtr isWhiteSpace, StripBeh avior stripBehavior) const {
390 } 370 if (!m_impl)
391 371 return String();
392 String String::simplifyWhiteSpace(StripBehavior stripBehavior) const 372 return m_impl->simplifyWhiteSpace(isWhiteSpace, stripBehavior);
393 { 373 }
394 if (!m_impl) 374
395 return String(); 375 String String::removeCharacters(CharacterMatchFunctionPtr findMatch) const {
396 return m_impl->simplifyWhiteSpace(stripBehavior); 376 if (!m_impl)
397 } 377 return String();
398 378 return m_impl->removeCharacters(findMatch);
399 String String::simplifyWhiteSpace(IsWhiteSpaceFunctionPtr isWhiteSpace, StripBeh avior stripBehavior) const 379 }
400 { 380
401 if (!m_impl) 381 String String::foldCase() const {
402 return String(); 382 if (!m_impl)
403 return m_impl->simplifyWhiteSpace(isWhiteSpace, stripBehavior); 383 return String();
404 } 384 return m_impl->foldCase();
405 385 }
406 String String::removeCharacters(CharacterMatchFunctionPtr findMatch) const 386
407 { 387 Vector<UChar> String::charactersWithNullTermination() const {
408 if (!m_impl) 388 if (!m_impl)
409 return String(); 389 return Vector<UChar>();
410 return m_impl->removeCharacters(findMatch); 390
411 } 391 Vector<UChar> result;
412 392 result.reserveInitialCapacity(length() + 1);
413 String String::foldCase() const 393 appendTo(result);
414 { 394 result.append('\0');
415 if (!m_impl) 395 return result;
416 return String(); 396 }
417 return m_impl->foldCase(); 397
418 } 398 unsigned String::copyTo(UChar* buffer, unsigned pos, unsigned maxLength) const {
419 399 unsigned length = this->length();
420 Vector<UChar> String::charactersWithNullTermination() const 400 RELEASE_ASSERT(pos <= length);
421 { 401 unsigned numCharacters = std::min(length - pos, maxLength);
422 if (!m_impl) 402 if (!numCharacters)
423 return Vector<UChar>(); 403 return 0;
424 404 if (is8Bit())
425 Vector<UChar> result; 405 StringImpl::copyChars(buffer, characters8() + pos, numCharacters);
426 result.reserveInitialCapacity(length() + 1); 406 else
427 appendTo(result); 407 StringImpl::copyChars(buffer, characters16() + pos, numCharacters);
428 result.append('\0'); 408 return numCharacters;
429 return result; 409 }
430 } 410
431 411 String String::format(const char* format, ...) {
432 unsigned String::copyTo(UChar* buffer, unsigned pos, unsigned maxLength) const 412 va_list args;
433 { 413 va_start(args, format);
434 unsigned length = this->length(); 414
435 RELEASE_ASSERT(pos <= length); 415 // Do the format once to get the length.
436 unsigned numCharacters = std::min(length - pos, maxLength);
437 if (!numCharacters)
438 return 0;
439 if (is8Bit())
440 StringImpl::copyChars(buffer, characters8() + pos, numCharacters);
441 else
442 StringImpl::copyChars(buffer, characters16() + pos, numCharacters);
443 return numCharacters;
444 }
445
446 String String::format(const char *format, ...)
447 {
448 va_list args;
449 va_start(args, format);
450
451 // Do the format once to get the length.
452 #if COMPILER(MSVC) 416 #if COMPILER(MSVC)
453 int result = _vscprintf(format, args); 417 int result = _vscprintf(format, args);
454 #else 418 #else
455 char ch; 419 char ch;
456 int result = vsnprintf(&ch, 1, format, args); 420 int result = vsnprintf(&ch, 1, format, args);
457 // We need to call va_end() and then va_start() again here, as the 421 // We need to call va_end() and then va_start() again here, as the
458 // contents of args is undefined after the call to vsnprintf 422 // contents of args is undefined after the call to vsnprintf
459 // according to http://man.cx/snprintf(3) 423 // according to http://man.cx/snprintf(3)
460 // 424 //
461 // Not calling va_end/va_start here happens to work on lots of 425 // Not calling va_end/va_start here happens to work on lots of
462 // systems, but fails e.g. on 64bit Linux. 426 // systems, but fails e.g. on 64bit Linux.
463 #endif 427 #endif
464 va_end(args); 428 va_end(args);
465 429
466 if (result == 0) 430 if (result == 0)
467 return String(""); 431 return String("");
468 if (result < 0) 432 if (result < 0)
469 return String(); 433 return String();
470 434
471 Vector<char, 256> buffer; 435 Vector<char, 256> buffer;
472 unsigned len = result; 436 unsigned len = result;
473 buffer.grow(len + 1); 437 buffer.grow(len + 1);
474 438
475 va_start(args, format); 439 va_start(args, format);
476 // Now do the formatting again, guaranteed to fit. 440 // Now do the formatting again, guaranteed to fit.
477 vsnprintf(buffer.data(), buffer.size(), format, args); 441 vsnprintf(buffer.data(), buffer.size(), format, args);
478 442
479 va_end(args); 443 va_end(args);
480 444
481 return StringImpl::create(reinterpret_cast<const LChar*>(buffer.data()), len ); 445 return StringImpl::create(reinterpret_cast<const LChar*>(buffer.data()), len);
482 } 446 }
483 447
484 String String::number(int number) 448 String String::number(int number) {
485 { 449 return numberToStringSigned<String>(number);
486 return numberToStringSigned<String>(number); 450 }
487 } 451
488 452 String String::number(unsigned number) {
489 String String::number(unsigned number) 453 return numberToStringUnsigned<String>(number);
490 { 454 }
491 return numberToStringUnsigned<String>(number); 455
492 } 456 String String::number(long number) {
493 457 return numberToStringSigned<String>(number);
494 String String::number(long number) 458 }
495 { 459
496 return numberToStringSigned<String>(number); 460 String String::number(unsigned long number) {
497 } 461 return numberToStringUnsigned<String>(number);
498 462 }
499 String String::number(unsigned long number) 463
500 { 464 String String::number(long long number) {
501 return numberToStringUnsigned<String>(number); 465 return numberToStringSigned<String>(number);
502 } 466 }
503 467
504 String String::number(long long number) 468 String String::number(unsigned long long number) {
505 { 469 return numberToStringUnsigned<String>(number);
506 return numberToStringSigned<String>(number); 470 }
507 } 471
508 472 String String::number(double number, unsigned precision, TrailingZerosTruncating Policy trailingZerosTruncatingPolicy) {
509 String String::number(unsigned long long number) 473 NumberToStringBuffer buffer;
510 { 474 return String(numberToFixedPrecisionString(number, precision, buffer, trailing ZerosTruncatingPolicy == TruncateTrailingZeros));
511 return numberToStringUnsigned<String>(number); 475 }
512 } 476
513 477 String String::numberToStringECMAScript(double number) {
514 String String::number(double number, unsigned precision, TrailingZerosTruncating Policy trailingZerosTruncatingPolicy) 478 NumberToStringBuffer buffer;
515 { 479 return String(numberToString(number, buffer));
516 NumberToStringBuffer buffer; 480 }
517 return String(numberToFixedPrecisionString(number, precision, buffer, traili ngZerosTruncatingPolicy == TruncateTrailingZeros)); 481
518 } 482 String String::numberToStringFixedWidth(double number, unsigned decimalPlaces) {
519 483 NumberToStringBuffer buffer;
520 String String::numberToStringECMAScript(double number) 484 return String(numberToFixedWidthString(number, decimalPlaces, buffer));
521 { 485 }
522 NumberToStringBuffer buffer; 486
523 return String(numberToString(number, buffer)); 487 int String::toIntStrict(bool* ok, int base) const {
524 } 488 if (!m_impl) {
525 489 if (ok)
526 String String::numberToStringFixedWidth(double number, unsigned decimalPlaces) 490 *ok = false;
527 { 491 return 0;
528 NumberToStringBuffer buffer; 492 }
529 return String(numberToFixedWidthString(number, decimalPlaces, buffer)); 493 return m_impl->toIntStrict(ok, base);
530 } 494 }
531 495
532 int String::toIntStrict(bool* ok, int base) const 496 unsigned String::toUIntStrict(bool* ok, int base) const {
533 { 497 if (!m_impl) {
534 if (!m_impl) { 498 if (ok)
535 if (ok) 499 *ok = false;
536 *ok = false; 500 return 0;
537 return 0; 501 }
538 } 502 return m_impl->toUIntStrict(ok, base);
539 return m_impl->toIntStrict(ok, base); 503 }
540 } 504
541 505 int64_t String::toInt64Strict(bool* ok, int base) const {
542 unsigned String::toUIntStrict(bool* ok, int base) const 506 if (!m_impl) {
543 { 507 if (ok)
544 if (!m_impl) { 508 *ok = false;
545 if (ok) 509 return 0;
546 *ok = false; 510 }
547 return 0; 511 return m_impl->toInt64Strict(ok, base);
548 } 512 }
549 return m_impl->toUIntStrict(ok, base); 513
550 } 514 uint64_t String::toUInt64Strict(bool* ok, int base) const {
551 515 if (!m_impl) {
552 int64_t String::toInt64Strict(bool* ok, int base) const 516 if (ok)
553 { 517 *ok = false;
554 if (!m_impl) { 518 return 0;
555 if (ok) 519 }
556 *ok = false; 520 return m_impl->toUInt64Strict(ok, base);
557 return 0; 521 }
558 } 522
559 return m_impl->toInt64Strict(ok, base); 523 int String::toInt(bool* ok) const {
560 } 524 if (!m_impl) {
561 525 if (ok)
562 uint64_t String::toUInt64Strict(bool* ok, int base) const 526 *ok = false;
563 { 527 return 0;
564 if (!m_impl) { 528 }
565 if (ok) 529 return m_impl->toInt(ok);
566 *ok = false; 530 }
567 return 0; 531
568 } 532 unsigned String::toUInt(bool* ok) const {
569 return m_impl->toUInt64Strict(ok, base); 533 if (!m_impl) {
570 } 534 if (ok)
571 535 *ok = false;
572 int String::toInt(bool* ok) const 536 return 0;
573 { 537 }
574 if (!m_impl) { 538 return m_impl->toUInt(ok);
575 if (ok) 539 }
576 *ok = false; 540
577 return 0; 541 int64_t String::toInt64(bool* ok) const {
578 } 542 if (!m_impl) {
579 return m_impl->toInt(ok); 543 if (ok)
580 } 544 *ok = false;
581 545 return 0;
582 unsigned String::toUInt(bool* ok) const 546 }
583 { 547 return m_impl->toInt64(ok);
584 if (!m_impl) { 548 }
585 if (ok) 549
586 *ok = false; 550 uint64_t String::toUInt64(bool* ok) const {
587 return 0; 551 if (!m_impl) {
588 } 552 if (ok)
589 return m_impl->toUInt(ok); 553 *ok = false;
590 } 554 return 0;
591 555 }
592 int64_t String::toInt64(bool* ok) const 556 return m_impl->toUInt64(ok);
593 { 557 }
594 if (!m_impl) { 558
595 if (ok) 559 double String::toDouble(bool* ok) const {
596 *ok = false; 560 if (!m_impl) {
597 return 0; 561 if (ok)
598 } 562 *ok = false;
599 return m_impl->toInt64(ok); 563 return 0.0;
600 } 564 }
601 565 return m_impl->toDouble(ok);
602 uint64_t String::toUInt64(bool* ok) const 566 }
603 { 567
604 if (!m_impl) { 568 float String::toFloat(bool* ok) const {
605 if (ok) 569 if (!m_impl) {
606 *ok = false; 570 if (ok)
607 return 0; 571 *ok = false;
608 } 572 return 0.0f;
609 return m_impl->toUInt64(ok); 573 }
610 } 574 return m_impl->toFloat(ok);
611 575 }
612 double String::toDouble(bool* ok) const 576
613 { 577 String String::isolatedCopy() const {
614 if (!m_impl) { 578 if (!m_impl)
615 if (ok) 579 return String();
616 *ok = false; 580 return m_impl->isolatedCopy();
617 return 0.0; 581 }
618 } 582
619 return m_impl->toDouble(ok); 583 bool String::isSafeToSendToAnotherThread() const {
620 } 584 if (!impl())
621 585 return true;
622 float String::toFloat(bool* ok) const 586 if (impl()->isStatic())
623 { 587 return true;
624 if (!m_impl) { 588 // AtomicStrings are not safe to send between threads as ~StringImpl()
625 if (ok) 589 // will try to remove them from the wrong AtomicStringTable.
626 *ok = false; 590 if (impl()->isAtomic())
627 return 0.0f;
628 }
629 return m_impl->toFloat(ok);
630 }
631
632 String String::isolatedCopy() const
633 {
634 if (!m_impl)
635 return String();
636 return m_impl->isolatedCopy();
637 }
638
639 bool String::isSafeToSendToAnotherThread() const
640 {
641 if (!impl())
642 return true;
643 if (impl()->isStatic())
644 return true;
645 // AtomicStrings are not safe to send between threads as ~StringImpl()
646 // will try to remove them from the wrong AtomicStringTable.
647 if (impl()->isAtomic())
648 return false;
649 if (impl()->hasOneRef())
650 return true;
651 return false; 591 return false;
652 } 592 if (impl()->hasOneRef())
653 593 return true;
654 void String::split(const String& separator, bool allowEmptyEntries, Vector<Strin g>& result) const 594 return false;
655 { 595 }
656 result.clear(); 596
657 597 void String::split(const String& separator, bool allowEmptyEntries, Vector<Strin g>& result) const {
658 unsigned startPos = 0; 598 result.clear();
659 size_t endPos; 599
660 while ((endPos = find(separator, startPos)) != kNotFound) { 600 unsigned startPos = 0;
661 if (allowEmptyEntries || startPos != endPos) 601 size_t endPos;
662 result.append(substring(startPos, endPos - startPos)); 602 while ((endPos = find(separator, startPos)) != kNotFound) {
663 startPos = endPos + separator.length(); 603 if (allowEmptyEntries || startPos != endPos)
664 } 604 result.append(substring(startPos, endPos - startPos));
665 if (allowEmptyEntries || startPos != length()) 605 startPos = endPos + separator.length();
666 result.append(substring(startPos)); 606 }
667 } 607 if (allowEmptyEntries || startPos != length())
668 608 result.append(substring(startPos));
669 void String::split(UChar separator, bool allowEmptyEntries, Vector<String>& resu lt) const 609 }
670 { 610
671 result.clear(); 611 void String::split(UChar separator, bool allowEmptyEntries, Vector<String>& resu lt) const {
672 612 result.clear();
673 unsigned startPos = 0; 613
674 size_t endPos; 614 unsigned startPos = 0;
675 while ((endPos = find(separator, startPos)) != kNotFound) { 615 size_t endPos;
676 if (allowEmptyEntries || startPos != endPos) 616 while ((endPos = find(separator, startPos)) != kNotFound) {
677 result.append(substring(startPos, endPos - startPos)); 617 if (allowEmptyEntries || startPos != endPos)
678 startPos = endPos + 1; 618 result.append(substring(startPos, endPos - startPos));
679 } 619 startPos = endPos + 1;
680 if (allowEmptyEntries || startPos != length()) 620 }
681 result.append(substring(startPos)); 621 if (allowEmptyEntries || startPos != length())
682 } 622 result.append(substring(startPos));
683 623 }
684 CString String::ascii() const 624
685 { 625 CString String::ascii() const {
686 // Printable ASCII characters 32..127 and the null character are 626 // Printable ASCII characters 32..127 and the null character are
687 // preserved, characters outside of this range are converted to '?'. 627 // preserved, characters outside of this range are converted to '?'.
688 628
689 unsigned length = this->length(); 629 unsigned length = this->length();
690 if (!length) { 630 if (!length) {
691 char* characterBuffer; 631 char* characterBuffer;
692 return CString::newUninitialized(length, characterBuffer); 632 return CString::newUninitialized(length, characterBuffer);
693 } 633 }
694 634
695 if (this->is8Bit()) { 635 if (this->is8Bit()) {
696 const LChar* characters = this->characters8(); 636 const LChar* characters = this->characters8();
697
698 char* characterBuffer;
699 CString result = CString::newUninitialized(length, characterBuffer);
700
701 for (unsigned i = 0; i < length; ++i) {
702 LChar ch = characters[i];
703 characterBuffer[i] = ch && (ch < 0x20 || ch > 0x7f) ? '?' : ch;
704 }
705
706 return result;
707 }
708
709 const UChar* characters = this->characters16();
710 637
711 char* characterBuffer; 638 char* characterBuffer;
712 CString result = CString::newUninitialized(length, characterBuffer); 639 CString result = CString::newUninitialized(length, characterBuffer);
713 640
714 for (unsigned i = 0; i < length; ++i) { 641 for (unsigned i = 0; i < length; ++i) {
715 UChar ch = characters[i]; 642 LChar ch = characters[i];
716 characterBuffer[i] = ch && (ch < 0x20 || ch > 0x7f) ? '?' : static_cast< char>(ch); 643 characterBuffer[i] = ch && (ch < 0x20 || ch > 0x7f) ? '?' : ch;
717 } 644 }
718 645
719 return result; 646 return result;
720 } 647 }
721 648
722 CString String::latin1() const 649 const UChar* characters = this->characters16();
723 { 650
724 // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are 651 char* characterBuffer;
725 // preserved, characters outside of this range are converted to '?'. 652 CString result = CString::newUninitialized(length, characterBuffer);
726 653
727 unsigned length = this->length(); 654 for (unsigned i = 0; i < length; ++i) {
728 655 UChar ch = characters[i];
729 if (!length) 656 characterBuffer[i] = ch && (ch < 0x20 || ch > 0x7f) ? '?' : static_cast<char >(ch);
730 return CString("", 0); 657 }
731 658
732 if (is8Bit()) 659 return result;
733 return CString(reinterpret_cast<const char*>(this->characters8()), lengt h); 660 }
734 661
662 CString String::latin1() const {
663 // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are
664 // preserved, characters outside of this range are converted to '?'.
665
666 unsigned length = this->length();
667
668 if (!length)
669 return CString("", 0);
670
671 if (is8Bit())
672 return CString(reinterpret_cast<const char*>(this->characters8()), length);
673
674 const UChar* characters = this->characters16();
675
676 char* characterBuffer;
677 CString result = CString::newUninitialized(length, characterBuffer);
678
679 for (unsigned i = 0; i < length; ++i) {
680 UChar ch = characters[i];
681 characterBuffer[i] = ch > 0xff ? '?' : static_cast<char>(ch);
682 }
683
684 return result;
685 }
686
687 // Helper to write a three-byte UTF-8 code point to the buffer, caller must chec k room is available.
688 static inline void putUTF8Triple(char*& buffer, UChar ch) {
689 ASSERT(ch >= 0x0800);
690 *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0);
691 *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80);
692 *buffer++ = static_cast<char>((ch & 0x3F) | 0x80);
693 }
694
695 CString String::utf8(UTF8ConversionMode mode) const {
696 unsigned length = this->length();
697
698 if (!length)
699 return CString("", 0);
700
701 // Allocate a buffer big enough to hold all the characters
702 // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes).
703 // Optimization ideas, if we find this function is hot:
704 // * We could speculatively create a CStringBuffer to contain 'length'
705 // characters, and resize if necessary (i.e. if the buffer contains
706 // non-ascii characters). (Alternatively, scan the buffer first for
707 // ascii characters, so we know this will be sufficient).
708 // * We could allocate a CStringBuffer with an appropriate size to
709 // have a good chance of being able to write the string into the
710 // buffer without reallocing (say, 1.5 x length).
711 if (length > std::numeric_limits<unsigned>::max() / 3)
712 return CString();
713 Vector<char, 1024> bufferVector(length * 3);
714
715 char* buffer = bufferVector.data();
716
717 if (is8Bit()) {
718 const LChar* characters = this->characters8();
719
720 ConversionResult result = convertLatin1ToUTF8(&characters, characters + leng th, &buffer, buffer + bufferVector.size());
721 ASSERT_UNUSED(result, result != targetExhausted); // (length * 3) should be sufficient for any conversion
722 } else {
735 const UChar* characters = this->characters16(); 723 const UChar* characters = this->characters16();
736 724
737 char* characterBuffer; 725 if (mode == StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD) {
738 CString result = CString::newUninitialized(length, characterBuffer); 726 const UChar* charactersEnd = characters + length;
739 727 char* bufferEnd = buffer + bufferVector.size();
740 for (unsigned i = 0; i < length; ++i) { 728 while (characters < charactersEnd) {
741 UChar ch = characters[i]; 729 // Use strict conversion to detect unpaired surrogates.
742 characterBuffer[i] = ch > 0xff ? '?' : static_cast<char>(ch); 730 ConversionResult result = convertUTF16ToUTF8(&characters, charactersEnd, &buffer, bufferEnd, true);
731 ASSERT(result != targetExhausted);
732 // Conversion fails when there is an unpaired surrogate. Put
733 // replacement character (U+FFFD) instead of the unpaired
734 // surrogate.
735 if (result != conversionOK) {
736 ASSERT((0xD800 <= *characters && *characters <= 0xDFFF));
737 // There should be room left, since one UChar hasn't been
738 // converted.
739 ASSERT((buffer + 3) <= bufferEnd);
740 putUTF8Triple(buffer, replacementCharacter);
741 ++characters;
742 }
743 }
744 } else {
745 bool strict = mode == StrictUTF8Conversion;
746 ConversionResult result = convertUTF16ToUTF8(&characters, characters + len gth, &buffer, buffer + bufferVector.size(), strict);
747 ASSERT(result != targetExhausted); // (length * 3) should be sufficient f or any conversion
748
749 // Only produced from strict conversion.
750 if (result == sourceIllegal) {
751 ASSERT(strict);
752 return CString();
753 }
754
755 // Check for an unconverted high surrogate.
756 if (result == sourceExhausted) {
757 if (strict)
758 return CString();
759 // This should be one unpaired high surrogate. Treat it the same
760 // was as an unpaired high surrogate would have been handled in
761 // the middle of a string with non-strict conversion - which is
762 // to say, simply encode it to UTF-8.
763 ASSERT((characters + 1) == (this->characters16() + length));
764 ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF));
765 // There should be room left, since one UChar hasn't been
766 // converted.
767 ASSERT((buffer + 3) <= (buffer + bufferVector.size()));
768 putUTF8Triple(buffer, *characters);
769 }
743 } 770 }
744 771 }
745 return result; 772
746 } 773 return CString(bufferVector.data(), buffer - bufferVector.data());
747 774 }
748 // Helper to write a three-byte UTF-8 code point to the buffer, caller must chec k room is available. 775
749 static inline void putUTF8Triple(char*& buffer, UChar ch) 776 String String::make8BitFrom16BitSource(const UChar* source, size_t length) {
750 { 777 if (!length)
751 ASSERT(ch >= 0x0800); 778 return emptyString();
752 *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); 779
753 *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); 780 LChar* destination;
754 *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); 781 String result = String::createUninitialized(length, destination);
755 } 782
756 783 copyLCharsFromUCharSource(destination, source, length);
757 CString String::utf8(UTF8ConversionMode mode) const 784
758 { 785 return result;
759 unsigned length = this->length(); 786 }
760 787
761 if (!length) 788 String String::make16BitFrom8BitSource(const LChar* source, size_t length) {
762 return CString("", 0); 789 if (!length)
763 790 return emptyString16Bit();
764 // Allocate a buffer big enough to hold all the characters 791
765 // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). 792 UChar* destination;
766 // Optimization ideas, if we find this function is hot: 793 String result = String::createUninitialized(length, destination);
767 // * We could speculatively create a CStringBuffer to contain 'length' 794
768 // characters, and resize if necessary (i.e. if the buffer contains 795 StringImpl::copyChars(destination, source, length);
769 // non-ascii characters). (Alternatively, scan the buffer first for 796
770 // ascii characters, so we know this will be sufficient). 797 return result;
771 // * We could allocate a CStringBuffer with an appropriate size to 798 }
772 // have a good chance of being able to write the string into the 799
773 // buffer without reallocing (say, 1.5 x length). 800 String String::fromUTF8(const LChar* stringStart, size_t length) {
774 if (length > std::numeric_limits<unsigned>::max() / 3) 801 RELEASE_ASSERT(length <= std::numeric_limits<unsigned>::max());
775 return CString(); 802
776 Vector<char, 1024> bufferVector(length * 3); 803 if (!stringStart)
777 804 return String();
778 char* buffer = bufferVector.data(); 805
779 806 if (!length)
780 if (is8Bit()) { 807 return emptyString();
781 const LChar* characters = this->characters8(); 808
782 809 if (charactersAreAllASCII(stringStart, length))
783 ConversionResult result = convertLatin1ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size()); 810 return StringImpl::create(stringStart, length);
784 ASSERT_UNUSED(result, result != targetExhausted); // (length * 3) should be sufficient for any conversion 811
785 } else { 812 Vector<UChar, 1024> buffer(length);
786 const UChar* characters = this->characters16(); 813 UChar* bufferStart = buffer.data();
787 814
788 if (mode == StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD) { 815 UChar* bufferCurrent = bufferStart;
789 const UChar* charactersEnd = characters + length; 816 const char* stringCurrent = reinterpret_cast<const char*>(stringStart);
790 char* bufferEnd = buffer + bufferVector.size(); 817 if (convertUTF8ToUTF16(&stringCurrent, reinterpret_cast<const char*>(stringSta rt + length), &bufferCurrent, bufferCurrent + buffer.size()) != conversionOK)
791 while (characters < charactersEnd) { 818 return String();
792 // Use strict conversion to detect unpaired surrogates. 819
793 ConversionResult result = convertUTF16ToUTF8(&characters, charac tersEnd, &buffer, bufferEnd, true); 820 unsigned utf16Length = bufferCurrent - bufferStart;
794 ASSERT(result != targetExhausted); 821 ASSERT(utf16Length < length);
795 // Conversion fails when there is an unpaired surrogate. Put 822 return StringImpl::create(bufferStart, utf16Length);
796 // replacement character (U+FFFD) instead of the unpaired 823 }
797 // surrogate. 824
798 if (result != conversionOK) { 825 String String::fromUTF8(const LChar* string) {
799 ASSERT((0xD800 <= *characters && *characters <= 0xDFFF)); 826 if (!string)
800 // There should be room left, since one UChar hasn't been 827 return String();
801 // converted. 828 return fromUTF8(string, strlen(reinterpret_cast<const char*>(string)));
802 ASSERT((buffer + 3) <= bufferEnd); 829 }
803 putUTF8Triple(buffer, replacementCharacter); 830
804 ++characters; 831 String String::fromUTF8(const CString& s) {
805 } 832 return fromUTF8(s.data());
806 } 833 }
807 } else { 834
808 bool strict = mode == StrictUTF8Conversion; 835 String String::fromUTF8WithLatin1Fallback(const LChar* string, size_t size) {
809 ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), strict); 836 String utf8 = fromUTF8(string, size);
810 ASSERT(result != targetExhausted); // (length * 3) should be suffici ent for any conversion 837 if (!utf8)
811 838 return String(string, size);
812 // Only produced from strict conversion. 839 return utf8;
813 if (result == sourceIllegal) {
814 ASSERT(strict);
815 return CString();
816 }
817
818 // Check for an unconverted high surrogate.
819 if (result == sourceExhausted) {
820 if (strict)
821 return CString();
822 // This should be one unpaired high surrogate. Treat it the same
823 // was as an unpaired high surrogate would have been handled in
824 // the middle of a string with non-strict conversion - which is
825 // to say, simply encode it to UTF-8.
826 ASSERT((characters + 1) == (this->characters16() + length));
827 ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF));
828 // There should be room left, since one UChar hasn't been
829 // converted.
830 ASSERT((buffer + 3) <= (buffer + bufferVector.size()));
831 putUTF8Triple(buffer, *characters);
832 }
833 }
834 }
835
836 return CString(bufferVector.data(), buffer - bufferVector.data());
837 }
838
839 String String::make8BitFrom16BitSource(const UChar* source, size_t length)
840 {
841 if (!length)
842 return emptyString();
843
844 LChar* destination;
845 String result = String::createUninitialized(length, destination);
846
847 copyLCharsFromUCharSource(destination, source, length);
848
849 return result;
850 }
851
852 String String::make16BitFrom8BitSource(const LChar* source, size_t length)
853 {
854 if (!length)
855 return emptyString16Bit();
856
857 UChar* destination;
858 String result = String::createUninitialized(length, destination);
859
860 StringImpl::copyChars(destination, source, length);
861
862 return result;
863 }
864
865 String String::fromUTF8(const LChar* stringStart, size_t length)
866 {
867 RELEASE_ASSERT(length <= std::numeric_limits<unsigned>::max());
868
869 if (!stringStart)
870 return String();
871
872 if (!length)
873 return emptyString();
874
875 if (charactersAreAllASCII(stringStart, length))
876 return StringImpl::create(stringStart, length);
877
878 Vector<UChar, 1024> buffer(length);
879 UChar* bufferStart = buffer.data();
880
881 UChar* bufferCurrent = bufferStart;
882 const char* stringCurrent = reinterpret_cast<const char*>(stringStart);
883 if (convertUTF8ToUTF16(&stringCurrent, reinterpret_cast<const char *>(string Start + length), &bufferCurrent, bufferCurrent + buffer.size()) != conversionOK)
884 return String();
885
886 unsigned utf16Length = bufferCurrent - bufferStart;
887 ASSERT(utf16Length < length);
888 return StringImpl::create(bufferStart, utf16Length);
889 }
890
891 String String::fromUTF8(const LChar* string)
892 {
893 if (!string)
894 return String();
895 return fromUTF8(string, strlen(reinterpret_cast<const char*>(string)));
896 }
897
898 String String::fromUTF8(const CString& s)
899 {
900 return fromUTF8(s.data());
901 }
902
903 String String::fromUTF8WithLatin1Fallback(const LChar* string, size_t size)
904 {
905 String utf8 = fromUTF8(string, size);
906 if (!utf8)
907 return String(string, size);
908 return utf8;
909 } 840 }
910 841
911 // String Operations 842 // String Operations
912 843
913 static bool isCharacterAllowedInBase(UChar c, int base) 844 static bool isCharacterAllowedInBase(UChar c, int base) {
914 { 845 if (c > 0x7F)
915 if (c > 0x7F) 846 return false;
916 return false; 847 if (isASCIIDigit(c))
848 return c - '0' < base;
849 if (isASCIIAlpha(c)) {
850 if (base > 36)
851 base = 36;
852 return (c >= 'a' && c < 'a' + base - 10) || (c >= 'A' && c < 'A' + base - 10 );
853 }
854 return false;
855 }
856
857 template <typename IntegralType, typename CharType>
858 static inline IntegralType toIntegralType(const CharType* data, size_t length, b ool* ok, int base) {
859 static const IntegralType integralMax = std::numeric_limits<IntegralType>::max ();
860 static const bool isSigned = std::numeric_limits<IntegralType>::is_signed;
861 const IntegralType maxMultiplier = integralMax / base;
862
863 IntegralType value = 0;
864 bool isOk = false;
865 bool isNegative = false;
866
867 if (!data)
868 goto bye;
869
870 // skip leading whitespace
871 while (length && isSpaceOrNewline(*data)) {
872 --length;
873 ++data;
874 }
875
876 if (isSigned && length && *data == '-') {
877 --length;
878 ++data;
879 isNegative = true;
880 } else if (length && *data == '+') {
881 --length;
882 ++data;
883 }
884
885 if (!length || !isCharacterAllowedInBase(*data, base))
886 goto bye;
887
888 while (length && isCharacterAllowedInBase(*data, base)) {
889 --length;
890 IntegralType digitValue;
891 CharType c = *data;
917 if (isASCIIDigit(c)) 892 if (isASCIIDigit(c))
918 return c - '0' < base; 893 digitValue = c - '0';
919 if (isASCIIAlpha(c)) { 894 else if (c >= 'a')
920 if (base > 36) 895 digitValue = c - 'a' + 10;
921 base = 36; 896 else
922 return (c >= 'a' && c < 'a' + base - 10) 897 digitValue = c - 'A' + 10;
923 || (c >= 'A' && c < 'A' + base - 10); 898
924 } 899 if (value > maxMultiplier || (value == maxMultiplier && digitValue > (integr alMax % base) + isNegative))
925 return false; 900 goto bye;
926 } 901
927 902 value = base * value + digitValue;
928 template <typename IntegralType, typename CharType> 903 ++data;
929 static inline IntegralType toIntegralType(const CharType* data, size_t length, b ool* ok, int base) 904 }
930 {
931 static const IntegralType integralMax = std::numeric_limits<IntegralType>::m ax();
932 static const bool isSigned = std::numeric_limits<IntegralType>::is_signed;
933 const IntegralType maxMultiplier = integralMax / base;
934
935 IntegralType value = 0;
936 bool isOk = false;
937 bool isNegative = false;
938
939 if (!data)
940 goto bye;
941
942 // skip leading whitespace
943 while (length && isSpaceOrNewline(*data)) {
944 --length;
945 ++data;
946 }
947
948 if (isSigned && length && *data == '-') {
949 --length;
950 ++data;
951 isNegative = true;
952 } else if (length && *data == '+') {
953 --length;
954 ++data;
955 }
956
957 if (!length || !isCharacterAllowedInBase(*data, base))
958 goto bye;
959
960 while (length && isCharacterAllowedInBase(*data, base)) {
961 --length;
962 IntegralType digitValue;
963 CharType c = *data;
964 if (isASCIIDigit(c))
965 digitValue = c - '0';
966 else if (c >= 'a')
967 digitValue = c - 'a' + 10;
968 else
969 digitValue = c - 'A' + 10;
970
971 if (value > maxMultiplier || (value == maxMultiplier && digitValue > (in tegralMax % base) + isNegative))
972 goto bye;
973
974 value = base * value + digitValue;
975 ++data;
976 }
977 905
978 #if COMPILER(MSVC) 906 #if COMPILER(MSVC)
979 #pragma warning(push, 0) 907 #pragma warning(push, 0)
980 #pragma warning(disable:4146) 908 #pragma warning(disable : 4146)
981 #endif 909 #endif
982 910
983 if (isNegative) 911 if (isNegative)
984 value = -value; 912 value = -value;
985 913
986 #if COMPILER(MSVC) 914 #if COMPILER(MSVC)
987 #pragma warning(pop) 915 #pragma warning(pop)
988 #endif 916 #endif
989 917
990 // skip trailing space 918 // skip trailing space
991 while (length && isSpaceOrNewline(*data)) { 919 while (length && isSpaceOrNewline(*data)) {
992 --length; 920 --length;
993 ++data; 921 ++data;
994 } 922 }
995 923
996 if (!length) 924 if (!length)
997 isOk = true; 925 isOk = true;
998 bye: 926 bye:
927 if (ok)
928 *ok = isOk;
929 return isOk ? value : 0;
930 }
931
932 template <typename CharType>
933 static unsigned lengthOfCharactersAsInteger(const CharType* data, size_t length) {
934 size_t i = 0;
935
936 // Allow leading spaces.
937 for (; i != length; ++i) {
938 if (!isSpaceOrNewline(data[i]))
939 break;
940 }
941
942 // Allow sign.
943 if (i != length && (data[i] == '+' || data[i] == '-'))
944 ++i;
945
946 // Allow digits.
947 for (; i != length; ++i) {
948 if (!isASCIIDigit(data[i]))
949 break;
950 }
951
952 return i;
953 }
954
955 int charactersToIntStrict(const LChar* data, size_t length, bool* ok, int base) {
956 return toIntegralType<int, LChar>(data, length, ok, base);
957 }
958
959 int charactersToIntStrict(const UChar* data, size_t length, bool* ok, int base) {
960 return toIntegralType<int, UChar>(data, length, ok, base);
961 }
962
963 unsigned charactersToUIntStrict(const LChar* data, size_t length, bool* ok, int base) {
964 return toIntegralType<unsigned, LChar>(data, length, ok, base);
965 }
966
967 unsigned charactersToUIntStrict(const UChar* data, size_t length, bool* ok, int base) {
968 return toIntegralType<unsigned, UChar>(data, length, ok, base);
969 }
970
971 int64_t charactersToInt64Strict(const LChar* data, size_t length, bool* ok, int base) {
972 return toIntegralType<int64_t, LChar>(data, length, ok, base);
973 }
974
975 int64_t charactersToInt64Strict(const UChar* data, size_t length, bool* ok, int base) {
976 return toIntegralType<int64_t, UChar>(data, length, ok, base);
977 }
978
979 uint64_t charactersToUInt64Strict(const LChar* data, size_t length, bool* ok, in t base) {
980 return toIntegralType<uint64_t, LChar>(data, length, ok, base);
981 }
982
983 uint64_t charactersToUInt64Strict(const UChar* data, size_t length, bool* ok, in t base) {
984 return toIntegralType<uint64_t, UChar>(data, length, ok, base);
985 }
986
987 int charactersToInt(const LChar* data, size_t length, bool* ok) {
988 return toIntegralType<int, LChar>(data, lengthOfCharactersAsInteger<LChar>(dat a, length), ok, 10);
989 }
990
991 int charactersToInt(const UChar* data, size_t length, bool* ok) {
992 return toIntegralType<int, UChar>(data, lengthOfCharactersAsInteger(data, leng th), ok, 10);
993 }
994
995 unsigned charactersToUInt(const LChar* data, size_t length, bool* ok) {
996 return toIntegralType<unsigned, LChar>(data, lengthOfCharactersAsInteger<LChar >(data, length), ok, 10);
997 }
998
999 unsigned charactersToUInt(const UChar* data, size_t length, bool* ok) {
1000 return toIntegralType<unsigned, UChar>(data, lengthOfCharactersAsInteger<UChar >(data, length), ok, 10);
1001 }
1002
1003 int64_t charactersToInt64(const LChar* data, size_t length, bool* ok) {
1004 return toIntegralType<int64_t, LChar>(data, lengthOfCharactersAsInteger<LChar> (data, length), ok, 10);
1005 }
1006
1007 int64_t charactersToInt64(const UChar* data, size_t length, bool* ok) {
1008 return toIntegralType<int64_t, UChar>(data, lengthOfCharactersAsInteger<UChar> (data, length), ok, 10);
1009 }
1010
1011 uint64_t charactersToUInt64(const LChar* data, size_t length, bool* ok) {
1012 return toIntegralType<uint64_t, LChar>(data, lengthOfCharactersAsInteger<LChar >(data, length), ok, 10);
1013 }
1014
1015 uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok) {
1016 return toIntegralType<uint64_t, UChar>(data, lengthOfCharactersAsInteger<UChar >(data, length), ok, 10);
1017 }
1018
1019 enum TrailingJunkPolicy { DisallowTrailingJunk,
1020 AllowTrailingJunk };
1021
1022 template <typename CharType, TrailingJunkPolicy policy>
1023 static inline double toDoubleType(const CharType* data, size_t length, bool* ok, size_t& parsedLength) {
1024 size_t leadingSpacesLength = 0;
1025 while (leadingSpacesLength < length && isASCIISpace(data[leadingSpacesLength]) )
1026 ++leadingSpacesLength;
1027
1028 double number = parseDouble(data + leadingSpacesLength, length - leadingSpaces Length, parsedLength);
1029 if (!parsedLength) {
999 if (ok) 1030 if (ok)
1000 *ok = isOk; 1031 *ok = false;
1001 return isOk ? value : 0; 1032 return 0.0;
1002 } 1033 }
1003 1034
1004 template <typename CharType> 1035 parsedLength += leadingSpacesLength;
1005 static unsigned lengthOfCharactersAsInteger(const CharType* data, size_t length) 1036 if (ok)
1006 { 1037 *ok = policy == AllowTrailingJunk || parsedLength == length;
1007 size_t i = 0; 1038 return number;
1008 1039 }
1009 // Allow leading spaces. 1040
1010 for (; i != length; ++i) { 1041 double charactersToDouble(const LChar* data, size_t length, bool* ok) {
1011 if (!isSpaceOrNewline(data[i])) 1042 size_t parsedLength;
1012 break; 1043 return toDoubleType<LChar, DisallowTrailingJunk>(data, length, ok, parsedLengt h);
1013 } 1044 }
1014 1045
1015 // Allow sign. 1046 double charactersToDouble(const UChar* data, size_t length, bool* ok) {
1016 if (i != length && (data[i] == '+' || data[i] == '-')) 1047 size_t parsedLength;
1017 ++i; 1048 return toDoubleType<UChar, DisallowTrailingJunk>(data, length, ok, parsedLengt h);
1018 1049 }
1019 // Allow digits. 1050
1020 for (; i != length; ++i) { 1051 float charactersToFloat(const LChar* data, size_t length, bool* ok) {
1021 if (!isASCIIDigit(data[i])) 1052 // FIXME: This will return ok even when the string fits into a double but
1022 break; 1053 // not a float.
1023 } 1054 size_t parsedLength;
1024 1055 return static_cast<float>(toDoubleType<LChar, DisallowTrailingJunk>(data, leng th, ok, parsedLength));
1025 return i; 1056 }
1026 } 1057
1027 1058 float charactersToFloat(const UChar* data, size_t length, bool* ok) {
1028 int charactersToIntStrict(const LChar* data, size_t length, bool* ok, int base) 1059 // FIXME: This will return ok even when the string fits into a double but
1029 { 1060 // not a float.
1030 return toIntegralType<int, LChar>(data, length, ok, base); 1061 size_t parsedLength;
1031 } 1062 return static_cast<float>(toDoubleType<UChar, DisallowTrailingJunk>(data, leng th, ok, parsedLength));
1032 1063 }
1033 int charactersToIntStrict(const UChar* data, size_t length, bool* ok, int base) 1064
1034 { 1065 float charactersToFloat(const LChar* data, size_t length, size_t& parsedLength) {
1035 return toIntegralType<int, UChar>(data, length, ok, base); 1066 // FIXME: This will return ok even when the string fits into a double but
1036 } 1067 // not a float.
1037 1068 return static_cast<float>(toDoubleType<LChar, AllowTrailingJunk>(data, length, 0, parsedLength));
1038 unsigned charactersToUIntStrict(const LChar* data, size_t length, bool* ok, int base) 1069 }
1039 { 1070
1040 return toIntegralType<unsigned, LChar>(data, length, ok, base); 1071 float charactersToFloat(const UChar* data, size_t length, size_t& parsedLength) {
1041 } 1072 // FIXME: This will return ok even when the string fits into a double but
1042 1073 // not a float.
1043 unsigned charactersToUIntStrict(const UChar* data, size_t length, bool* ok, int base) 1074 return static_cast<float>(toDoubleType<UChar, AllowTrailingJunk>(data, length, 0, parsedLength));
1044 { 1075 }
1045 return toIntegralType<unsigned, UChar>(data, length, ok, base); 1076
1046 } 1077 const String& emptyString() {
1047 1078 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty()));
1048 int64_t charactersToInt64Strict(const LChar* data, size_t length, bool* ok, int base) 1079 return emptyString;
1049 { 1080 }
1050 return toIntegralType<int64_t, LChar>(data, length, ok, base); 1081
1051 } 1082 const String& emptyString16Bit() {
1052 1083 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty16Bit()));
1053 int64_t charactersToInt64Strict(const UChar* data, size_t length, bool* ok, int base) 1084 return emptyString;
1054 { 1085 }
1055 return toIntegralType<int64_t, UChar>(data, length, ok, base); 1086
1056 } 1087 } // namespace WTF
1057
1058 uint64_t charactersToUInt64Strict(const LChar* data, size_t length, bool* ok, in t base)
1059 {
1060 return toIntegralType<uint64_t, LChar>(data, length, ok, base);
1061 }
1062
1063 uint64_t charactersToUInt64Strict(const UChar* data, size_t length, bool* ok, in t base)
1064 {
1065 return toIntegralType<uint64_t, UChar>(data, length, ok, base);
1066 }
1067
1068 int charactersToInt(const LChar* data, size_t length, bool* ok)
1069 {
1070 return toIntegralType<int, LChar>(data, lengthOfCharactersAsInteger<LChar>(d ata, length), ok, 10);
1071 }
1072
1073 int charactersToInt(const UChar* data, size_t length, bool* ok)
1074 {
1075 return toIntegralType<int, UChar>(data, lengthOfCharactersAsInteger(data, le ngth), ok, 10);
1076 }
1077
1078 unsigned charactersToUInt(const LChar* data, size_t length, bool* ok)
1079 {
1080 return toIntegralType<unsigned, LChar>(data, lengthOfCharactersAsInteger<LCh ar>(data, length), ok, 10);
1081 }
1082
1083 unsigned charactersToUInt(const UChar* data, size_t length, bool* ok)
1084 {
1085 return toIntegralType<unsigned, UChar>(data, lengthOfCharactersAsInteger<UCh ar>(data, length), ok, 10);
1086 }
1087
1088 int64_t charactersToInt64(const LChar* data, size_t length, bool* ok)
1089 {
1090 return toIntegralType<int64_t, LChar>(data, lengthOfCharactersAsInteger<LCha r>(data, length), ok, 10);
1091 }
1092
1093 int64_t charactersToInt64(const UChar* data, size_t length, bool* ok)
1094 {
1095 return toIntegralType<int64_t, UChar>(data, lengthOfCharactersAsInteger<UCha r>(data, length), ok, 10);
1096 }
1097
1098 uint64_t charactersToUInt64(const LChar* data, size_t length, bool* ok)
1099 {
1100 return toIntegralType<uint64_t, LChar>(data, lengthOfCharactersAsInteger<LCh ar>(data, length), ok, 10);
1101 }
1102
1103 uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok)
1104 {
1105 return toIntegralType<uint64_t, UChar>(data, lengthOfCharactersAsInteger<UCh ar>(data, length), ok, 10);
1106 }
1107
1108 enum TrailingJunkPolicy { DisallowTrailingJunk, AllowTrailingJunk };
1109
1110 template <typename CharType, TrailingJunkPolicy policy>
1111 static inline double toDoubleType(const CharType* data, size_t length, bool* ok, size_t& parsedLength)
1112 {
1113 size_t leadingSpacesLength = 0;
1114 while (leadingSpacesLength < length && isASCIISpace(data[leadingSpacesLength ]))
1115 ++leadingSpacesLength;
1116
1117 double number = parseDouble(data + leadingSpacesLength, length - leadingSpac esLength, parsedLength);
1118 if (!parsedLength) {
1119 if (ok)
1120 *ok = false;
1121 return 0.0;
1122 }
1123
1124 parsedLength += leadingSpacesLength;
1125 if (ok)
1126 *ok = policy == AllowTrailingJunk || parsedLength == length;
1127 return number;
1128 }
1129
1130 double charactersToDouble(const LChar* data, size_t length, bool* ok)
1131 {
1132 size_t parsedLength;
1133 return toDoubleType<LChar, DisallowTrailingJunk>(data, length, ok, parsedLen gth);
1134 }
1135
1136 double charactersToDouble(const UChar* data, size_t length, bool* ok)
1137 {
1138 size_t parsedLength;
1139 return toDoubleType<UChar, DisallowTrailingJunk>(data, length, ok, parsedLen gth);
1140 }
1141
1142 float charactersToFloat(const LChar* data, size_t length, bool* ok)
1143 {
1144 // FIXME: This will return ok even when the string fits into a double but
1145 // not a float.
1146 size_t parsedLength;
1147 return static_cast<float>(toDoubleType<LChar, DisallowTrailingJunk>(data, le ngth, ok, parsedLength));
1148 }
1149
1150 float charactersToFloat(const UChar* data, size_t length, bool* ok)
1151 {
1152 // FIXME: This will return ok even when the string fits into a double but
1153 // not a float.
1154 size_t parsedLength;
1155 return static_cast<float>(toDoubleType<UChar, DisallowTrailingJunk>(data, le ngth, ok, parsedLength));
1156 }
1157
1158 float charactersToFloat(const LChar* data, size_t length, size_t& parsedLength)
1159 {
1160 // FIXME: This will return ok even when the string fits into a double but
1161 // not a float.
1162 return static_cast<float>(toDoubleType<LChar, AllowTrailingJunk>(data, lengt h, 0, parsedLength));
1163 }
1164
1165 float charactersToFloat(const UChar* data, size_t length, size_t& parsedLength)
1166 {
1167 // FIXME: This will return ok even when the string fits into a double but
1168 // not a float.
1169 return static_cast<float>(toDoubleType<UChar, AllowTrailingJunk>(data, lengt h, 0, parsedLength));
1170 }
1171
1172 const String& emptyString()
1173 {
1174 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty()));
1175 return emptyString;
1176 }
1177
1178 const String& emptyString16Bit()
1179 {
1180 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty16Bit()));
1181 return emptyString;
1182 }
1183
1184 } // namespace WTF
1185 1088
1186 #ifndef NDEBUG 1089 #ifndef NDEBUG
1187 // For use in the debugger 1090 // For use in the debugger
1188 String* string(const char*); 1091 String* string(const char*);
1189 Vector<char> asciiDebug(StringImpl*); 1092 Vector<char> asciiDebug(StringImpl*);
1190 Vector<char> asciiDebug(String&); 1093 Vector<char> asciiDebug(String&);
1191 1094
1192 void String::show() const 1095 void String::show() const {
1193 { 1096 dataLogF("%s\n", asciiDebug(impl()).data());
1194 dataLogF("%s\n", asciiDebug(impl()).data());
1195 } 1097 }
1196 1098
1197 String* string(const char* s) 1099 String* string(const char* s) {
1198 { 1100 // leaks memory!
1199 // leaks memory! 1101 return new String(s);
1200 return new String(s);
1201 } 1102 }
1202 1103
1203 Vector<char> asciiDebug(StringImpl* impl) 1104 Vector<char> asciiDebug(StringImpl* impl) {
1204 { 1105 if (!impl)
1205 if (!impl) 1106 return asciiDebug(String("[null]").impl());
1206 return asciiDebug(String("[null]").impl());
1207 1107
1208 Vector<char> buffer; 1108 Vector<char> buffer;
1209 for (unsigned i = 0; i < impl->length(); ++i) { 1109 for (unsigned i = 0; i < impl->length(); ++i) {
1210 UChar ch = (*impl)[i]; 1110 UChar ch = (*impl)[i];
1211 if (isASCIIPrintable(ch)) { 1111 if (isASCIIPrintable(ch)) {
1212 if (ch == '\\') 1112 if (ch == '\\')
1213 buffer.append('\\'); 1113 buffer.append('\\');
1214 buffer.append(static_cast<char>(ch)); 1114 buffer.append(static_cast<char>(ch));
1215 } else { 1115 } else {
1216 buffer.append('\\'); 1116 buffer.append('\\');
1217 buffer.append('u'); 1117 buffer.append('u');
1218 appendUnsignedAsHexFixedSize(ch, buffer, 4); 1118 appendUnsignedAsHexFixedSize(ch, buffer, 4);
1219 }
1220 } 1119 }
1221 buffer.append('\0'); 1120 }
1222 return buffer; 1121 buffer.append('\0');
1122 return buffer;
1223 } 1123 }
1224 1124
1225 Vector<char> asciiDebug(String& string) 1125 Vector<char> asciiDebug(String& string) {
1226 { 1126 return asciiDebug(string.impl());
1227 return asciiDebug(string.impl());
1228 } 1127 }
1229 1128
1230 #endif 1129 #endif
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/WTFString.h ('k') | third_party/WebKit/Source/wtf/text/WTFStringTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698