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