1 /* 2 * (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22 #ifndef WTFString_h 23 #define WTFString_h 24 25 // This file would be called String.h, but that conflicts with <string.h> 26 // on systems without case-sensitive file systems. 27 28 #include "wtf/HashTableDeletedValueType.h" 29 #include "wtf/WTFExport.h" 30 #include "wtf/text/ASCIIFastPath.h" 31 #include "wtf/text/StringImpl.h" 32 #include "wtf/text/StringView.h" 33 34 #ifdef __OBJC__ 35 #include <objc/objc.h> 36 #endif 37 38 namespace WTF { 39 40 class CString; 41 struct StringHash; 42 43 // Declarations of string operations 44 45 WTF_EXPORT int charactersToIntStrict(const LChar*, size_t, bool* ok = 0, int base = 10); 46 WTF_EXPORT int charactersToIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10); 47 WTF_EXPORT unsigned charactersToUIntStrict(const LChar*, size_t, bool* ok = 0, int base = 10); 48 WTF_EXPORT unsigned charactersToUIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10); 49 WTF_EXPORT int64_t charactersToInt64Strict(const LChar*, size_t, bool* ok = 0, int base = 10); 50 WTF_EXPORT int64_t charactersToInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10); 51 WTF_EXPORT uint64_t charactersToUInt64Strict(const LChar*, size_t, bool* ok = 0, int base = 10); 52 WTF_EXPORT uint64_t charactersToUInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10); 53 WTF_EXPORT intptr_t charactersToIntPtrStrict(const LChar*, size_t, bool* ok = 0, int base = 10); 54 WTF_EXPORT intptr_t charactersToIntPtrStrict(const UChar*, size_t, bool* ok = 0, int base = 10); 55 56 WTF_EXPORT int charactersToInt(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 57 WTF_EXPORT int charactersToInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 58 WTF_EXPORT unsigned charactersToUInt(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 59 WTF_EXPORT unsigned charactersToUInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 60 WTF_EXPORT int64_t charactersToInt64(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 61 WTF_EXPORT int64_t charactersToInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 62 WTF_EXPORT uint64_t charactersToUInt64(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 63 WTF_EXPORT uint64_t charactersToUInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 64 WTF_EXPORT intptr_t charactersToIntPtr(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 65 WTF_EXPORT intptr_t charactersToIntPtr(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 66 67 // FIXME: Like the strict functions above, these give false for "ok" when there is trailing garbage. 68 // Like the non-strict functions above, these return the value when there is trailing garbage. 69 // It would be better if these were more consistent with the above functions instead. 70 WTF_EXPORT double charactersToDouble(const LChar*, size_t, bool* ok = 0); 71 WTF_EXPORT double charactersToDouble(const UChar*, size_t, bool* ok = 0); 72 WTF_EXPORT float charactersToFloat(const LChar*, size_t, bool* ok = 0); 73 WTF_EXPORT float charactersToFloat(const UChar*, size_t, bool* ok = 0); 74 WTF_EXPORT float charactersToFloat(const LChar*, size_t, size_t& parsedLength); 75 WTF_EXPORT float charactersToFloat(const UChar*, size_t, size_t& parsedLength); 76 77 enum TrailingZerosTruncatingPolicy { 78 KeepTrailingZeros, 79 TruncateTrailingZeros 80 }; 81 82 enum UTF8ConversionMode { 83 LenientUTF8Conversion, 84 StrictUTF8Conversion, 85 StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD 86 }; 87 88 template<bool isSpecialCharacter(UChar), typename CharacterType> 89 bool isAllSpecialCharacters(const CharacterType*, size_t); 90 91 // You can find documentation about this class in this doc: 92 // https://docs.google.com/document/d/1kOCUlJdh2WJMJGDf-WoEQhmnjKLaOYRbiHz5TiGJl14/edit?usp=sharing 93 class WTF_EXPORT String { 94 public: 95 // Construct a null string, distinguishable from an empty string. 96 String() { } 97 98 // Construct a string with UTF-16 data. 99 String(const UChar* characters, unsigned length); 100 101 // Construct a string by copying the contents of a vector. 102 // This method will never create a null string. Vectors with size() == 0 103 // will return the empty string. 104 // NOTE: This is different from String(vector.data(), vector.size()) 105 // which will sometimes return a null string when vector.data() is null 106 // which can only occur for vectors without inline capacity. 107 // See: https://bugs.webkit.org/show_bug.cgi?id=109792 108 template<size_t inlineCapacity> 109 explicit String(const Vector<UChar, inlineCapacity>&); 110 111 // Construct a string with UTF-16 data, from a null-terminated source. 112 String(const UChar*); 113 114 // Construct a string with latin1 data. 115 String(const LChar* characters, unsigned length); 116 String(const char* characters, unsigned length); 117 118 // Construct a string with latin1 data, from a null-terminated source. 119 String(const LChar* characters); 120 String(const char* characters); 121 122 // Construct a string referencing an existing StringImpl. 123 String(StringImpl* impl) : m_impl(impl) { } 124 String(PassRefPtr<StringImpl> impl) : m_impl(impl) { } 125 126 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 127 // We have to declare the copy constructor and copy assignment operator as well, otherwise 128 // they'll be implicitly deleted by adding the move constructor and move assignment operator. 129 String(const String& other) : m_impl(other.m_impl) { } 130 String(String&& other) : m_impl(other.m_impl.release()) { } 131 String& operator=(const String& other) { m_impl = other.m_impl; return *this; } 132 String& operator=(String&& other) { m_impl = other.m_impl.release(); return *this; } 133 #endif 134 135 // Inline the destructor. 136 ALWAYS_INLINE ~String() { } 137 138 void swap(String& o) { m_impl.swap(o.m_impl); } 139 140 template<typename CharType> 141 static String adopt(StringBuffer<CharType>& buffer) 142 { 143 if (!buffer.length()) 144 return StringImpl::empty(); 145 return String(buffer.release()); 146 } 147 148 bool isNull() const { return !m_impl; } 149 bool isEmpty() const { return !m_impl || !m_impl->length(); } 150 151 StringImpl* impl() const { return m_impl.get(); } 152 PassRefPtr<StringImpl> releaseImpl() { return m_impl.release(); } 153 154 unsigned length() const 155 { 156 if (!m_impl) 157 return 0; 158 return m_impl->length(); 159 } 160 161 const LChar* characters8() const 162 { 163 if (!m_impl) 164 return 0; 165 ASSERT(m_impl->is8Bit()); 166 return m_impl->characters8(); 167 } 168 169 const UChar* characters16() const 170 { 171 if (!m_impl) 172 return 0; 173 ASSERT(!m_impl->is8Bit()); 174 return m_impl->characters16(); 175 } 176 177 // Return characters8() or characters16() depending on CharacterType. 178 template <typename CharacterType> 179 inline const CharacterType* getCharacters() const; 180 181 bool is8Bit() const { return m_impl->is8Bit(); } 182 183 unsigned sizeInBytes() const 184 { 185 if (!m_impl) 186 return 0; 187 return m_impl->length() * (is8Bit() ? sizeof(LChar) : sizeof(UChar)); 188 } 189 190 CString ascii() const; 191 CString latin1() const; 192 CString utf8(UTF8ConversionMode = LenientUTF8Conversion) const; 193 194 UChar operator[](unsigned index) const 195 { 196 if (!m_impl || index >= m_impl->length()) 197 return 0; 198 return (*m_impl)[index]; 199 } 200 201 static String number(int); 202 static String number(unsigned); 203 static String number(long); 204 static String number(unsigned long); 205 static String number(long long); 206 static String number(unsigned long long); 207 208 static String number(double, unsigned precision = 6, TrailingZerosTruncatingPolicy = TruncateTrailingZeros); 209 210 // Number to String conversion following the ECMAScript definition. 211 static String numberToStringECMAScript(double); 212 static String numberToStringFixedWidth(double, unsigned decimalPlaces); 213 214 // Find a single character or string, also with match function & latin1 forms. 215 size_t find(UChar c, unsigned start = 0) const 216 { return m_impl ? m_impl->find(c, start) : kNotFound; } 217 218 size_t find(const String& str) const 219 { return m_impl ? m_impl->find(str.impl()) : kNotFound; } 220 size_t find(const String& str, unsigned start) const 221 { return m_impl ? m_impl->find(str.impl(), start) : kNotFound; } 222 223 size_t find(CharacterMatchFunctionPtr matchFunction, unsigned start = 0) const 224 { return m_impl ? m_impl->find(matchFunction, start) : kNotFound; } 225 size_t find(const LChar* str, unsigned start = 0) const 226 { return m_impl ? m_impl->find(str, start) : kNotFound; } 227 228 size_t findNextLineStart(unsigned start = 0) const 229 { return m_impl ? m_impl->findNextLineStart(start) : kNotFound; } 230 231 // Find the last instance of a single character or string. 232 size_t reverseFind(UChar c, unsigned start = UINT_MAX) const 233 { return m_impl ? m_impl->reverseFind(c, start) : kNotFound; } 234 size_t reverseFind(const String& str, unsigned start = UINT_MAX) const 235 { return m_impl ? m_impl->reverseFind(str.impl(), start) : kNotFound; } 236 237 // Case insensitive string matching. 238 size_t findIgnoringCase(const LChar* str, unsigned start = 0) const 239 { return m_impl ? m_impl->findIgnoringCase(str, start) : kNotFound; } 240 size_t findIgnoringCase(const String& str, unsigned start = 0) const 241 { return m_impl ? m_impl->findIgnoringCase(str.impl(), start) : kNotFound; } 242 size_t reverseFindIgnoringCase(const String& str, unsigned start = UINT_MAX) const 243 { return m_impl ? m_impl->reverseFindIgnoringCase(str.impl(), start) : kNotFound; } 244 245 // Wrappers for find & reverseFind adding dynamic sensitivity check. 246 size_t find(const LChar* str, unsigned start, bool caseSensitive) const 247 { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); } 248 size_t find(const String& str, unsigned start, bool caseSensitive) const 249 { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); } 250 size_t reverseFind(const String& str, unsigned start, bool caseSensitive) const 251 { return caseSensitive ? reverseFind(str, start) : reverseFindIgnoringCase(str, start); } 252 253 Vector<UChar> charactersWithNullTermination() const; 254 unsigned copyTo(UChar* buffer, unsigned pos, unsigned maxLength) const; 255 256 template<size_t inlineCapacity> 257 void appendTo(Vector<UChar, inlineCapacity>&, unsigned pos = 0, unsigned len = UINT_MAX) const; 258 259 template<typename BufferType> 260 void appendTo(BufferType&, unsigned pos = 0, unsigned len = UINT_MAX) const; 261 262 template<size_t inlineCapacity> 263 void prependTo(Vector<UChar, inlineCapacity>&, unsigned pos = 0, unsigned len = UINT_MAX) const; 264 265 UChar32 characterStartingAt(unsigned) const; 266 267 bool contains(UChar c) const { return find(c) != kNotFound; } 268 bool contains(const LChar* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != kNotFound; } 269 bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != kNotFound; } 270 271 bool startsWith(const String& s, bool caseSensitive = true) const 272 { return m_impl ? m_impl->startsWith(s.impl(), caseSensitive) : s.isEmpty(); } 273 bool startsWith(UChar character) const 274 { return m_impl ? m_impl->startsWith(character) : false; } 275 template<unsigned matchLength> 276 bool startsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const 277 { return m_impl ? m_impl->startsWith<matchLength>(prefix, caseSensitive) : !matchLength; } 278 279 bool endsWith(const String& s, bool caseSensitive = true) const 280 { return m_impl ? m_impl->endsWith(s.impl(), caseSensitive) : s.isEmpty(); } 281 bool endsWith(UChar character) const 282 { return m_impl ? m_impl->endsWith(character) : false; } 283 template<unsigned matchLength> 284 bool endsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const 285 { return m_impl ? m_impl->endsWith<matchLength>(prefix, caseSensitive) : !matchLength; } 286 287 void append(const String&); 288 void append(LChar); 289 void append(char c) { append(static_cast<LChar>(c)); } 290 void append(UChar); 291 void append(const LChar*, unsigned length); 292 void append(const char* charactersToAppend, unsigned length) { append(reinterpret_cast<const LChar*>(charactersToAppend), length); } 293 void append(const UChar*, unsigned length); 294 void insert(const String&, unsigned pos); 295 void insert(const LChar*, unsigned length, unsigned pos); 296 void insert(const UChar*, unsigned length, unsigned pos); 297 298 String& replace(UChar a, UChar b) { if (m_impl) m_impl = m_impl->replace(a, b); return *this; } 299 String& replace(UChar a, const String& b) { if (m_impl) m_impl = m_impl->replace(a, b.impl()); return *this; } 300 String& replace(const String& a, const String& b) { if (m_impl) m_impl = m_impl->replace(a.impl(), b.impl()); return *this; } 301 String& replace(unsigned index, unsigned len, const String& b) { if (m_impl) m_impl = m_impl->replace(index, len, b.impl()); return *this; } 302 303 template<unsigned charactersCount> 304 ALWAYS_INLINE String& replaceWithLiteral(UChar a, const char (&characters)[charactersCount]) 305 { 306 if (m_impl) 307 m_impl = m_impl->replace(a, characters, charactersCount - 1); 308 309 return *this; 310 } 311 312 void fill(UChar c) { if (m_impl) m_impl = m_impl->fill(c); } 313 314 void ensure16Bit(); 315 316 void truncate(unsigned len); 317 void remove(unsigned pos, int len = 1); 318 319 String substring(unsigned pos, unsigned len = UINT_MAX) const; 320 String left(unsigned len) const { return substring(0, len); } 321 String right(unsigned len) const { return substring(length() - len, len); } 322 323 StringView createView() const { return StringView(impl()); } 324 StringView createView(unsigned offset, unsigned length) const { return StringView(impl(), offset, length); } 325 326 // Returns a lowercase/uppercase version of the string 327 String lower() const; 328 String upper() const; 329 330 String lower(const AtomicString& localeIdentifier) const; 331 String upper(const AtomicString& localeIdentifier) const; 332 333 String stripWhiteSpace() const; 334 String stripWhiteSpace(IsWhiteSpaceFunctionPtr) const; 335 String simplifyWhiteSpace(StripBehavior stripBehavior = StripExtraWhiteSpace) const; 336 String simplifyWhiteSpace(IsWhiteSpaceFunctionPtr, StripBehavior stripBehavior = StripExtraWhiteSpace) const; 337 338 String removeCharacters(CharacterMatchFunctionPtr) const; 339 template<bool isSpecialCharacter(UChar)> bool isAllSpecialCharacters() const; 340 341 // Return the string with case folded for case insensitive comparison. 342 String foldCase() const; 343 344 static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2); 345 346 // Returns an uninitialized string. The characters needs to be written 347 // into the buffer returned in data before the returned string is used. 348 // Failure to do this will have unpredictable results. 349 static String createUninitialized(unsigned length, UChar*& data) { return StringImpl::createUninitialized(length, data); } 350 static String createUninitialized(unsigned length, LChar*& data) { return StringImpl::createUninitialized(length, data); } 351 352 void split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const; 353 void split(const String& separator, Vector<String>& result) const 354 { 355 split(separator, false, result); 356 } 357 void split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const; 358 void split(UChar separator, Vector<String>& result) const 359 { 360 split(separator, false, result); 361 } 362 363 int toIntStrict(bool* ok = 0, int base = 10) const; 364 unsigned toUIntStrict(bool* ok = 0, int base = 10) const; 365 int64_t toInt64Strict(bool* ok = 0, int base = 10) const; 366 uint64_t toUInt64Strict(bool* ok = 0, int base = 10) const; 367 intptr_t toIntPtrStrict(bool* ok = 0, int base = 10) const; 368 369 int toInt(bool* ok = 0) const; 370 unsigned toUInt(bool* ok = 0) const; 371 int64_t toInt64(bool* ok = 0) const; 372 uint64_t toUInt64(bool* ok = 0) const; 373 intptr_t toIntPtr(bool* ok = 0) const; 374 375 // FIXME: Like the strict functions above, these give false for "ok" when there is trailing garbage. 376 // Like the non-strict functions above, these return the value when there is trailing garbage. 377 // It would be better if these were more consistent with the above functions instead. 378 double toDouble(bool* ok = 0) const; 379 float toFloat(bool* ok = 0) const; 380 381 bool percentage(int& percentage) const; 382 383 String isolatedCopy() const; 384 bool isSafeToSendToAnotherThread() const; 385 386 #if USE(CF) 387 String(CFStringRef); 388 RetainPtr<CFStringRef> createCFString() const; 389 #endif 390 391 #ifdef __OBJC__ 392 String(NSString*); 393 394 // This conversion maps NULL to "", which loses the meaning of NULL, but we 395 // need this mapping because AppKit crashes when passed nil NSStrings. 396 operator NSString*() const { if (!m_impl) return @""; return *m_impl; } 397 #endif 398 399 static String make8BitFrom16BitSource(const UChar*, size_t); 400 template<size_t inlineCapacity> 401 static String make8BitFrom16BitSource(const Vector<UChar, inlineCapacity>& buffer) 402 { 403 return make8BitFrom16BitSource(buffer.data(), buffer.size()); 404 } 405 406 static String make16BitFrom8BitSource(const LChar*, size_t); 407 408 // String::fromUTF8 will return a null string if 409 // the input data contains invalid UTF-8 sequences. 410 static String fromUTF8(const LChar*, size_t); 411 static String fromUTF8(const LChar*); 412 static String fromUTF8(const char* s, size_t length) { return fromUTF8(reinterpret_cast<const LChar*>(s), length); }; 413 static String fromUTF8(const char* s) { return fromUTF8(reinterpret_cast<const LChar*>(s)); }; 414 static String fromUTF8(const CString&); 415 416 // Tries to convert the passed in string to UTF-8, but will fall back to Latin-1 if the string is not valid UTF-8. 417 static String fromUTF8WithLatin1Fallback(const LChar*, size_t); 418 static String fromUTF8WithLatin1Fallback(const char* s, size_t length) { return fromUTF8WithLatin1Fallback(reinterpret_cast<const LChar*>(s), length); }; 419 420 bool containsOnlyASCII() const; 421 bool containsOnlyLatin1() const; 422 bool containsOnlyWhitespace() const { return !m_impl || m_impl->containsOnlyWhitespace(); } 423 424 // Hash table deleted values, which are only constructed and never copied or destroyed. 425 String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { } 426 bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); } 427 428 #ifndef NDEBUG 429 void show() const; 430 #endif 431 432 // Workaround for a compiler bug. Use operator[] instead. 433 UChar characterAt(unsigned index) const 434 { 435 if (!m_impl || index >= m_impl->length()) 436 return 0; 437 return (*m_impl)[index]; 438 } 439 440 private: 441 typedef struct ImplicitConversionFromWTFStringToBoolDisallowed* (String::*UnspecifiedBoolType); 442 operator UnspecifiedBoolType() const; 443 444 template <typename CharacterType> 445 void removeInternal(const CharacterType*, unsigned, int); 446 447 template <typename CharacterType> 448 void appendInternal(CharacterType); 449 450 RefPtr<StringImpl> m_impl; 451 }; 452 453 inline bool operator==(const String& a, const String& b) { return equal(a.impl(), b.impl()); } 454 inline bool operator==(const String& a, const LChar* b) { return equal(a.impl(), b); } 455 inline bool operator==(const String& a, const char* b) { return equal(a.impl(), reinterpret_cast<const LChar*>(b)); } 456 inline bool operator==(const LChar* a, const String& b) { return equal(a, b.impl()); } 457 inline bool operator==(const char* a, const String& b) { return equal(reinterpret_cast<const LChar*>(a), b.impl()); } 458 template<size_t inlineCapacity> 459 inline bool operator==(const Vector<char, inlineCapacity>& a, const String& b) { return equal(b.impl(), a.data(), a.size()); } 460 template<size_t inlineCapacity> 461 inline bool operator==(const String& a, const Vector<char, inlineCapacity>& b) { return b == a; } 462 463 464 inline bool operator!=(const String& a, const String& b) { return !equal(a.impl(), b.impl()); } 465 inline bool operator!=(const String& a, const LChar* b) { return !equal(a.impl(), b); } 466 inline bool operator!=(const String& a, const char* b) { return !equal(a.impl(), reinterpret_cast<const LChar*>(b)); } 467 inline bool operator!=(const LChar* a, const String& b) { return !equal(a, b.impl()); } 468 inline bool operator!=(const char* a, const String& b) { return !equal(reinterpret_cast<const LChar*>(a), b.impl()); } 469 template<size_t inlineCapacity> 470 inline bool operator!=(const Vector<char, inlineCapacity>& a, const String& b) { return !(a == b); } 471 template<size_t inlineCapacity> 472 inline bool operator!=(const String& a, const Vector<char, inlineCapacity>& b) { return b != a; } 473 474 inline bool equalIgnoringCase(const String& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); } 475 inline bool equalIgnoringCase(const String& a, const LChar* b) { return equalIgnoringCase(a.impl(), b); } 476 inline bool equalIgnoringCase(const String& a, const char* b) { return equalIgnoringCase(a.impl(), reinterpret_cast<const LChar*>(b)); } 477 inline bool equalIgnoringCase(const LChar* a, const String& b) { return equalIgnoringCase(a, b.impl()); } 478 inline bool equalIgnoringCase(const char* a, const String& b) { return equalIgnoringCase(reinterpret_cast<const LChar*>(a), b.impl()); } 479 480 inline bool equalPossiblyIgnoringCase(const String& a, const String& b, bool ignoreCase) 481 { 482 return ignoreCase ? equalIgnoringCase(a, b) : (a == b); 483 } 484 485 inline bool equalIgnoringNullity(const String& a, const String& b) { return equalIgnoringNullity(a.impl(), b.impl()); } 486 487 template<size_t inlineCapacity> 488 inline bool equalIgnoringNullity(const Vector<UChar, inlineCapacity>& a, const String& b) { return equalIgnoringNullity(a, b.impl()); } 489 490 inline bool operator!(const String& str) { return str.isNull(); } 491 492 inline void swap(String& a, String& b) { a.swap(b); } 493 494 // Definitions of string operations 495 496 template<size_t inlineCapacity> 497 String::String(const Vector<UChar, inlineCapacity>& vector) 498 : m_impl(vector.size() ? StringImpl::create(vector.data(), vector.size()) : StringImpl::empty()) 499 { 500 } 501 502 template<> 503 inline const LChar* String::getCharacters<LChar>() const 504 { 505 ASSERT(is8Bit()); 506 return characters8(); 507 } 508 509 template<> 510 inline const UChar* String::getCharacters<UChar>() const 511 { 512 ASSERT(!is8Bit()); 513 return characters16(); 514 } 515 516 inline bool String::containsOnlyLatin1() const 517 { 518 if (isEmpty()) 519 return true; 520 521 if (is8Bit()) 522 return true; 523 524 const UChar* characters = characters16(); 525 UChar ored = 0; 526 for (size_t i = 0; i < m_impl->length(); ++i) 527 ored |= characters[i]; 528 return !(ored & 0xFF00); 529 } 530 531 532 #ifdef __OBJC__ 533 // This is for situations in WebKit where the long standing behavior has been 534 // "nil if empty", so we try to maintain longstanding behavior for the sake of 535 // entrenched clients 536 inline NSString* nsStringNilIfEmpty(const String& str) { return str.isEmpty() ? nil : (NSString*)str; } 537 #endif 538 539 inline bool String::containsOnlyASCII() const 540 { 541 if (isEmpty()) 542 return true; 543 544 if (is8Bit()) 545 return charactersAreAllASCII(characters8(), m_impl->length()); 546 547 return charactersAreAllASCII(characters16(), m_impl->length()); 548 } 549 550 WTF_EXPORT int codePointCompare(const String&, const String&); 551 552 inline bool codePointCompareLessThan(const String& a, const String& b) 553 { 554 return codePointCompare(a.impl(), b.impl()) < 0; 555 } 556 557 template<size_t inlineCapacity> 558 inline void append(Vector<UChar, inlineCapacity>& vector, const String& string) 559 { 560 unsigned length = string.length(); 561 if (!length) 562 return; 563 if (string.is8Bit()) { 564 const LChar* characters8 = string.characters8(); 565 vector.reserveCapacity(vector.size() + length); 566 for (size_t i = 0; i < length; ++i) 567 vector.uncheckedAppend(characters8[i]); 568 } else { 569 vector.append(string.characters16(), length); 570 } 571 } 572 573 template<typename CharacterType> 574 inline void appendNumber(Vector<CharacterType>& vector, unsigned char number) 575 { 576 int numberLength = number > 99 ? 3 : (number > 9 ? 2 : 1); 577 size_t vectorSize = vector.size(); 578 vector.grow(vectorSize + numberLength); 579 580 switch (numberLength) { 581 case 3: 582 vector[vectorSize + 2] = number % 10 + '0'; 583 number /= 10; 584 585 case 2: 586 vector[vectorSize + 1] = number % 10 + '0'; 587 number /= 10; 588 589 case 1: 590 vector[vectorSize] = number % 10 + '0'; 591 } 592 } 593 594 template<bool isSpecialCharacter(UChar), typename CharacterType> 595 inline bool isAllSpecialCharacters(const CharacterType* characters, size_t length) 596 { 597 for (size_t i = 0; i < length; ++i) { 598 if (!isSpecialCharacter(characters[i])) 599 return false; 600 } 601 return true; 602 } 603 604 template<bool isSpecialCharacter(UChar)> 605 inline bool String::isAllSpecialCharacters() const 606 { 607 size_t len = length(); 608 609 if (!len) 610 return true; 611 612 if (is8Bit()) 613 return WTF::isAllSpecialCharacters<isSpecialCharacter, LChar>(characters8(), len); 614 return WTF::isAllSpecialCharacters<isSpecialCharacter, UChar>(characters16(), len); 615 } 616 617 template<size_t inlineCapacity> 618 inline void String::appendTo(Vector<UChar, inlineCapacity>& result, unsigned pos, unsigned len) const 619 { 620 unsigned numberOfCharactersToCopy = std::min(len, length() - pos); 621 if (!numberOfCharactersToCopy) 622 return; 623 result.reserveCapacity(result.size() + numberOfCharactersToCopy); 624 if (is8Bit()) { 625 const LChar* characters8 = m_impl->characters8(); 626 for (size_t i = 0; i < numberOfCharactersToCopy; ++i) 627 result.uncheckedAppend(characters8[pos + i]); 628 } else { 629 const UChar* characters16 = m_impl->characters16(); 630 result.append(characters16 + pos, numberOfCharactersToCopy); 631 } 632 } 633 634 template<typename BufferType> 635 inline void String::appendTo(BufferType& result, unsigned pos, unsigned len) const 636 { 637 unsigned numberOfCharactersToCopy = std::min(len, length() - pos); 638 if (!numberOfCharactersToCopy) 639 return; 640 if (is8Bit()) 641 result.append(m_impl->characters8() + pos, numberOfCharactersToCopy); 642 else 643 result.append(m_impl->characters16() + pos, numberOfCharactersToCopy); 644 } 645 646 template<size_t inlineCapacity> 647 inline void String::prependTo(Vector<UChar, inlineCapacity>& result, unsigned pos, unsigned len) const 648 { 649 unsigned numberOfCharactersToCopy = std::min(len, length() - pos); 650 if (!numberOfCharactersToCopy) 651 return; 652 if (is8Bit()) { 653 size_t oldSize = result.size(); 654 result.resize(oldSize + numberOfCharactersToCopy); 655 memmove(result.data() + numberOfCharactersToCopy, result.data(), oldSize * sizeof(UChar)); 656 StringImpl::copyChars(result.data(), m_impl->characters8() + pos, numberOfCharactersToCopy); 657 } else { 658 result.prepend(m_impl->characters16() + pos, numberOfCharactersToCopy); 659 } 660 } 661 662 // StringHash is the default hash for String 663 template<typename T> struct DefaultHash; 664 template<> struct DefaultHash<String> { 665 typedef StringHash Hash; 666 }; 667 668 // Shared global empty string. 669 WTF_EXPORT const String& emptyString(); 670 671 #ifndef STRING_HIDE_GLOBALS 672 673 WTF_EXPORT extern const String xmlnsWithColon; 674 675 #endif // STRING_HIDE_GLOBALS 676 677 } // namespace WTF 678 679 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(String); 680 681 using WTF::CString; 682 using WTF::KeepTrailingZeros; 683 using WTF::StrictUTF8Conversion; 684 using WTF::StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD; 685 using WTF::String; 686 using WTF::emptyString; 687 using WTF::append; 688 using WTF::appendNumber; 689 using WTF::charactersAreAllASCII; 690 using WTF::charactersToIntStrict; 691 using WTF::charactersToUIntStrict; 692 using WTF::charactersToInt64Strict; 693 using WTF::charactersToUInt64Strict; 694 using WTF::charactersToIntPtrStrict; 695 using WTF::charactersToInt; 696 using WTF::charactersToUInt; 697 using WTF::charactersToInt64; 698 using WTF::charactersToUInt64; 699 using WTF::charactersToIntPtr; 700 using WTF::charactersToDouble; 701 using WTF::charactersToFloat; 702 using WTF::equal; 703 using WTF::equalIgnoringCase; 704 using WTF::find; 705 using WTF::isAllSpecialCharacters; 706 using WTF::isSpaceOrNewline; 707 using WTF::reverseFind; 708 709 #include "wtf/text/AtomicString.h" 710 #endif // WTFString_h 711