1/* 2 * (C) 1999 Lars Knoll (knoll@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/text/ASCIIFastPath.h> 29#include <wtf/text/StringImpl.h> 30 31#ifdef __OBJC__ 32#include <objc/objc.h> 33#endif 34 35namespace WTF { 36 37class CString; 38struct StringHash; 39 40// Declarations of string operations 41 42WTF_EXPORT_STRING_API int charactersToIntStrict(const LChar*, size_t, bool* ok = 0, int base = 10); 43WTF_EXPORT_STRING_API int charactersToIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10); 44WTF_EXPORT_STRING_API unsigned charactersToUIntStrict(const LChar*, size_t, bool* ok = 0, int base = 10); 45WTF_EXPORT_STRING_API unsigned charactersToUIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10); 46int64_t charactersToInt64Strict(const LChar*, size_t, bool* ok = 0, int base = 10); 47int64_t charactersToInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10); 48uint64_t charactersToUInt64Strict(const LChar*, size_t, bool* ok = 0, int base = 10); 49uint64_t charactersToUInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10); 50intptr_t charactersToIntPtrStrict(const LChar*, size_t, bool* ok = 0, int base = 10); 51intptr_t charactersToIntPtrStrict(const UChar*, size_t, bool* ok = 0, int base = 10); 52 53WTF_EXPORT_STRING_API int charactersToInt(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 54WTF_EXPORT_STRING_API int charactersToInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 55unsigned charactersToUInt(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 56unsigned charactersToUInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 57int64_t charactersToInt64(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 58int64_t charactersToInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 59uint64_t charactersToUInt64(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 60uint64_t charactersToUInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 61intptr_t charactersToIntPtr(const LChar*, size_t, bool* ok = 0); // ignores trailing garbage 62intptr_t charactersToIntPtr(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage 63 64// FIXME: Like the strict functions above, these give false for "ok" when there is trailing garbage. 65// Like the non-strict functions above, these return the value when there is trailing garbage. 66// It would be better if these were more consistent with the above functions instead. 67WTF_EXPORT_STRING_API double charactersToDouble(const LChar*, size_t, bool* ok = 0); 68WTF_EXPORT_STRING_API double charactersToDouble(const UChar*, size_t, bool* ok = 0); 69WTF_EXPORT_STRING_API float charactersToFloat(const LChar*, size_t, bool* ok = 0); 70WTF_EXPORT_STRING_API float charactersToFloat(const UChar*, size_t, bool* ok = 0); 71WTF_EXPORT_STRING_API float charactersToFloat(const LChar*, size_t, size_t& parsedLength); 72WTF_EXPORT_STRING_API float charactersToFloat(const UChar*, size_t, size_t& parsedLength); 73 74class ASCIILiteral; 75 76enum TrailingZerosTruncatingPolicy { 77 KeepTrailingZeros, 78 TruncateTrailingZeros 79}; 80 81template<bool isSpecialCharacter(UChar), typename CharacterType> 82bool isAllSpecialCharacters(const CharacterType*, size_t); 83 84class String { 85public: 86 // Construct a null string, distinguishable from an empty string. 87 String() { } 88 89 // Construct a string with UTF-16 data. 90 WTF_EXPORT_STRING_API String(const UChar* characters, unsigned length); 91 92 // Construct a string by copying the contents of a vector. To avoid 93 // copying, consider using String::adopt instead. 94 // This method will never create a null string. Vectors with size() == 0 95 // will return the empty string. 96 // NOTE: This is different from String(vector.data(), vector.size()) 97 // which will sometimes return a null string when vector.data() is null 98 // which can only occur for vectors without inline capacity. 99 // See: https://bugs.webkit.org/show_bug.cgi?id=109792 100 template<size_t inlineCapacity, typename OverflowHandler> 101 explicit String(const Vector<UChar, inlineCapacity, OverflowHandler>&); 102 103 // Construct a string with UTF-16 data, from a null-terminated source. 104 WTF_EXPORT_STRING_API String(const UChar*); 105 106 // Construct a string with latin1 data. 107 WTF_EXPORT_STRING_API String(const LChar* characters, unsigned length); 108 WTF_EXPORT_STRING_API String(const char* characters, unsigned length); 109 110 // Construct a string with latin1 data, from a null-terminated source. 111 WTF_EXPORT_STRING_API String(const LChar* characters); 112 WTF_EXPORT_STRING_API String(const char* characters); 113 114 // Construct a string referencing an existing StringImpl. 115 String(StringImpl& impl) : m_impl(&impl) { } 116 String(StringImpl* impl) : m_impl(impl) { } 117 String(PassRefPtr<StringImpl> impl) : m_impl(impl) { } 118 String(PassRef<StringImpl>&& impl) : m_impl(std::forward<PassRef<StringImpl>>(impl)) { } 119 String(RefPtr<StringImpl>&& impl) : m_impl(impl) { } 120 121 // Construct a string from a constant string literal. 122 WTF_EXPORT_STRING_API String(ASCIILiteral characters); 123 124 // Construct a string from a constant string literal. 125 // This constructor is the "big" version, as it put the length in the function call and generate bigger code. 126 enum ConstructFromLiteralTag { ConstructFromLiteral }; 127 template<unsigned charactersCount> 128 String(const char (&characters)[charactersCount], ConstructFromLiteralTag) : m_impl(StringImpl::createFromLiteral<charactersCount>(characters)) { } 129 130 // We have to declare the copy constructor and copy assignment operator as well, otherwise 131 // they'll be implicitly deleted by adding the move constructor and move assignment operator. 132 String(const String& other) : m_impl(other.m_impl) { } 133 String(String&& other) : m_impl(other.m_impl.release()) { } 134 String& operator=(const String& other) { m_impl = other.m_impl; return *this; } 135 String& operator=(String&& other) { m_impl = other.m_impl.release(); return *this; } 136 137 // Inline the destructor. 138 ALWAYS_INLINE ~String() { } 139 140 void swap(String& o) { m_impl.swap(o.m_impl); } 141 142 static String adopt(StringBuffer<LChar>& buffer) { return StringImpl::adopt(buffer); } 143 static String adopt(StringBuffer<UChar>& buffer) { return StringImpl::adopt(buffer); } 144 template<typename CharacterType, size_t inlineCapacity, typename OverflowHandler> 145 static String adopt(Vector<CharacterType, inlineCapacity, OverflowHandler>& vector) { return StringImpl::adopt(vector); } 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* characters() 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 WTF_EXPORT_STRING_API CString ascii() const; 190 WTF_EXPORT_STRING_API CString latin1() const; 191 192 WTF_EXPORT_STRING_API CString utf8(ConversionMode = LenientConversion) const; 193 194 UChar at(unsigned index) const 195 { 196 if (!m_impl || index >= m_impl->length()) 197 return 0; 198 return (*m_impl)[index]; 199 } 200 UChar operator[](unsigned index) const { return at(index); } 201 202 WTF_EXPORT_STRING_API static String number(int); 203 WTF_EXPORT_STRING_API static String number(unsigned int); 204 WTF_EXPORT_STRING_API static String number(long); 205 WTF_EXPORT_STRING_API static String number(unsigned long); 206 WTF_EXPORT_STRING_API static String number(long long); 207 WTF_EXPORT_STRING_API static String number(unsigned long long); 208 209 WTF_EXPORT_STRING_API static String number(double, unsigned precision = 6, TrailingZerosTruncatingPolicy = TruncateTrailingZeros); 210 211 // Number to String conversion following the ECMAScript definition. 212 WTF_EXPORT_STRING_API static String numberToStringECMAScript(double); 213 WTF_EXPORT_STRING_API static String numberToStringFixedWidth(double, unsigned decimalPlaces); 214 215 // Find a single character or string, also with match function & latin1 forms. 216 size_t find(UChar c, unsigned start = 0) const 217 { return m_impl ? m_impl->find(c, start) : notFound; } 218 219 size_t find(const String& str) const 220 { return m_impl ? m_impl->find(str.impl()) : notFound; } 221 size_t find(const String& str, unsigned start) const 222 { return m_impl ? m_impl->find(str.impl(), start) : notFound; } 223 224 size_t find(CharacterMatchFunctionPtr matchFunction, unsigned start = 0) const 225 { return m_impl ? m_impl->find(matchFunction, start) : notFound; } 226 size_t find(const LChar* str, unsigned start = 0) const 227 { return m_impl ? m_impl->find(str, start) : notFound; } 228 229 size_t findNextLineStart(unsigned start = 0) const 230 { return m_impl ? m_impl->findNextLineStart(start) : notFound; } 231 232 // Find the last instance of a single character or string. 233 size_t reverseFind(UChar c, unsigned start = UINT_MAX) const 234 { return m_impl ? m_impl->reverseFind(c, start) : notFound; } 235 size_t reverseFind(const String& str, unsigned start = UINT_MAX) const 236 { return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; } 237 238 // Case insensitive string matching. 239 size_t findIgnoringCase(const LChar* str, unsigned start = 0) const 240 { return m_impl ? m_impl->findIgnoringCase(str, start) : notFound; } 241 size_t findIgnoringCase(const String& str, unsigned start = 0) const 242 { return m_impl ? m_impl->findIgnoringCase(str.impl(), start) : notFound; } 243 size_t reverseFindIgnoringCase(const String& str, unsigned start = UINT_MAX) const 244 { return m_impl ? m_impl->reverseFindIgnoringCase(str.impl(), start) : notFound; } 245 246 // Wrappers for find & reverseFind adding dynamic sensitivity check. 247 size_t find(const LChar* str, unsigned start, bool caseSensitive) const 248 { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); } 249 size_t find(const String& str, unsigned start, bool caseSensitive) const 250 { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); } 251 size_t reverseFind(const String& str, unsigned start, bool caseSensitive) const 252 { return caseSensitive ? reverseFind(str, start) : reverseFindIgnoringCase(str, start); } 253 254 WTF_EXPORT_STRING_API Vector<UChar> charactersWithNullTermination() const; 255 256 WTF_EXPORT_STRING_API UChar32 characterStartingAt(unsigned) const; // Ditto. 257 258 bool contains(UChar c) const { return find(c) != notFound; } 259 bool contains(const LChar* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; } 260 bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; } 261 262 bool startsWith(const String& s) const 263 { return m_impl ? m_impl->startsWith(s.impl()) : s.isEmpty(); } 264 bool startsWith(const String& s, bool caseSensitive) const 265 { return m_impl ? m_impl->startsWith(s.impl(), caseSensitive) : s.isEmpty(); } 266 bool startsWith(UChar character) const 267 { return m_impl ? m_impl->startsWith(character) : false; } 268 template<unsigned matchLength> 269 bool startsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const 270 { return m_impl ? m_impl->startsWith<matchLength>(prefix, caseSensitive) : !matchLength; } 271 272 bool endsWith(const String& s, bool caseSensitive = true) const 273 { return m_impl ? m_impl->endsWith(s.impl(), caseSensitive) : s.isEmpty(); } 274 bool endsWith(UChar character) const 275 { return m_impl ? m_impl->endsWith(character) : false; } 276 bool endsWith(char character) const { return endsWith(static_cast<UChar>(character)); } 277 template<unsigned matchLength> 278 bool endsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const 279 { return m_impl ? m_impl->endsWith<matchLength>(prefix, caseSensitive) : !matchLength; } 280 281 WTF_EXPORT_STRING_API void append(const String&); 282 WTF_EXPORT_STRING_API void append(LChar); 283 void append(char c) { append(static_cast<LChar>(c)); }; 284 WTF_EXPORT_STRING_API void append(UChar); 285 WTF_EXPORT_STRING_API void append(const LChar*, unsigned length); 286 WTF_EXPORT_STRING_API void append(const UChar*, unsigned length); 287 WTF_EXPORT_STRING_API void insert(const String&, unsigned pos); 288 289 String& replace(UChar a, UChar b) { if (m_impl) m_impl = m_impl->replace(a, b); return *this; } 290 String& replace(UChar a, const String& b) { if (m_impl) m_impl = m_impl->replace(a, b.impl()); return *this; } 291 String& replace(const String& a, const String& b) { if (m_impl) m_impl = m_impl->replace(a.impl(), b.impl()); return *this; } 292 String& replace(unsigned index, unsigned len, const String& b) { if (m_impl) m_impl = m_impl->replace(index, len, b.impl()); return *this; } 293 294 template<unsigned charactersCount> 295 ALWAYS_INLINE String& replaceWithLiteral(UChar a, const char (&characters)[charactersCount]) 296 { 297 if (m_impl) 298 m_impl = m_impl->replace(a, characters, charactersCount - 1); 299 300 return *this; 301 } 302 303 void fill(UChar c) { if (m_impl) m_impl = m_impl->fill(c); } 304 305 WTF_EXPORT_STRING_API void truncate(unsigned len); 306 WTF_EXPORT_STRING_API void remove(unsigned pos, int len = 1); 307 308 WTF_EXPORT_STRING_API String substring(unsigned pos, unsigned len = UINT_MAX) const; 309 WTF_EXPORT_STRING_API String substringSharingImpl(unsigned pos, unsigned len = UINT_MAX) const; 310 String left(unsigned len) const { return substring(0, len); } 311 String right(unsigned len) const { return substring(length() - len, len); } 312 313 // Returns a lowercase/uppercase version of the string. 314 // The convertToASCIILowercase is useful in many contexts such as HTML where we don't 315 // want to do any conversion for non-ASCII letters. 316 WTF_EXPORT_STRING_API String convertToASCIILowercase() const; 317 WTF_EXPORT_STRING_API String lower() const; 318 WTF_EXPORT_STRING_API String upper() const; 319 320 WTF_EXPORT_STRING_API String lower(const AtomicString& localeIdentifier) const; 321 WTF_EXPORT_STRING_API String upper(const AtomicString& localeIdentifier) const; 322 323 WTF_EXPORT_STRING_API String stripWhiteSpace() const; 324 WTF_EXPORT_STRING_API String stripWhiteSpace(IsWhiteSpaceFunctionPtr) const; 325 WTF_EXPORT_STRING_API String simplifyWhiteSpace() const; 326 WTF_EXPORT_STRING_API String simplifyWhiteSpace(IsWhiteSpaceFunctionPtr) const; 327 328 WTF_EXPORT_STRING_API String removeCharacters(CharacterMatchFunctionPtr) const; 329 template<bool isSpecialCharacter(UChar)> bool isAllSpecialCharacters() const; 330 331 // Returns the string with case folded for case insensitive comparison. 332 // Use convertToASCIILowercase instead if ASCII case insensitive comparison is desired. 333 WTF_EXPORT_STRING_API String foldCase() const; 334 335 WTF_EXPORT_STRING_API static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2); 336 337 // Returns an uninitialized string. The characters needs to be written 338 // into the buffer returned in data before the returned string is used. 339 // Failure to do this will have unpredictable results. 340 static String createUninitialized(unsigned length, UChar*& data) { return StringImpl::createUninitialized(length, data); } 341 static String createUninitialized(unsigned length, LChar*& data) { return StringImpl::createUninitialized(length, data); } 342 343 WTF_EXPORT_STRING_API void split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const; 344 void split(const String& separator, Vector<String>& result) const 345 { 346 split(separator, false, result); 347 } 348 WTF_EXPORT_STRING_API void split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const; 349 void split(UChar separator, Vector<String>& result) const 350 { 351 split(separator, false, result); 352 } 353 354 WTF_EXPORT_STRING_API int toIntStrict(bool* ok = 0, int base = 10) const; 355 WTF_EXPORT_STRING_API unsigned toUIntStrict(bool* ok = 0, int base = 10) const; 356 WTF_EXPORT_STRING_API int64_t toInt64Strict(bool* ok = 0, int base = 10) const; 357 WTF_EXPORT_STRING_API uint64_t toUInt64Strict(bool* ok = 0, int base = 10) const; 358 intptr_t toIntPtrStrict(bool* ok = 0, int base = 10) const; 359 360 WTF_EXPORT_STRING_API int toInt(bool* ok = 0) const; 361 WTF_EXPORT_STRING_API unsigned toUInt(bool* ok = 0) const; 362 WTF_EXPORT_STRING_API int64_t toInt64(bool* ok = 0) const; 363 WTF_EXPORT_STRING_API uint64_t toUInt64(bool* ok = 0) const; 364 WTF_EXPORT_STRING_API intptr_t toIntPtr(bool* ok = 0) const; 365 366 // FIXME: Like the strict functions above, these give false for "ok" when there is trailing garbage. 367 // Like the non-strict functions above, these return the value when there is trailing garbage. 368 // It would be better if these were more consistent with the above functions instead. 369 WTF_EXPORT_STRING_API double toDouble(bool* ok = 0) const; 370 WTF_EXPORT_STRING_API float toFloat(bool* ok = 0) const; 371 372 bool percentage(int& percentage) const; 373 374#if COMPILER_SUPPORTS(CXX_REFERENCE_QUALIFIED_FUNCTIONS) 375 WTF_EXPORT_STRING_API String isolatedCopy() const &; 376 WTF_EXPORT_STRING_API String isolatedCopy() &&; 377#else 378 WTF_EXPORT_STRING_API String isolatedCopy() const; 379#endif 380 381 WTF_EXPORT_STRING_API bool isSafeToSendToAnotherThread() const; 382 383 // Prevent Strings from being implicitly convertable to bool as it will be ambiguous on any platform that 384 // allows implicit conversion to another pointer type (e.g., Mac allows implicit conversion to NSString*). 385 typedef struct ImplicitConversionFromWTFStringToBoolDisallowedA* (String::*UnspecifiedBoolTypeA); 386 typedef struct ImplicitConversionFromWTFStringToBoolDisallowedB* (String::*UnspecifiedBoolTypeB); 387 operator UnspecifiedBoolTypeA() const; 388 operator UnspecifiedBoolTypeB() const; 389 390#if USE(CF) 391 WTF_EXPORT_STRING_API String(CFStringRef); 392 WTF_EXPORT_STRING_API RetainPtr<CFStringRef> createCFString() const; 393#endif 394 395#ifdef __OBJC__ 396 WTF_EXPORT_STRING_API String(NSString*); 397 398 // This conversion maps NULL to "", which loses the meaning of NULL, but we 399 // need this mapping because AppKit crashes when passed nil NSStrings. 400 operator NSString*() const { if (!m_impl) return @""; return *m_impl; } 401#endif 402 403 WTF_EXPORT_STRING_API static String make8BitFrom16BitSource(const UChar*, size_t); 404 template<size_t inlineCapacity> 405 static String make8BitFrom16BitSource(const Vector<UChar, inlineCapacity>& buffer) 406 { 407 return make8BitFrom16BitSource(buffer.data(), buffer.size()); 408 } 409 410 WTF_EXPORT_STRING_API static String make16BitFrom8BitSource(const LChar*, size_t); 411 412 // String::fromUTF8 will return a null string if 413 // the input data contains invalid UTF-8 sequences. 414 WTF_EXPORT_STRING_API static String fromUTF8(const LChar*, size_t); 415 WTF_EXPORT_STRING_API static String fromUTF8(const LChar*); 416 static String fromUTF8(const char* s, size_t length) { return fromUTF8(reinterpret_cast<const LChar*>(s), length); }; 417 static String fromUTF8(const char* s) { return fromUTF8(reinterpret_cast<const LChar*>(s)); }; 418 WTF_EXPORT_STRING_API static String fromUTF8(const CString&); 419 420 // 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. 421 WTF_EXPORT_STRING_API static String fromUTF8WithLatin1Fallback(const LChar*, size_t); 422 static String fromUTF8WithLatin1Fallback(const char* s, size_t length) { return fromUTF8WithLatin1Fallback(reinterpret_cast<const LChar*>(s), length); }; 423 424 // Determines the writing direction using the Unicode Bidi Algorithm rules P2 and P3. 425 UCharDirection defaultWritingDirection(bool* hasStrongDirectionality = nullptr) const 426 { 427 if (m_impl) 428 return m_impl->defaultWritingDirection(hasStrongDirectionality); 429 if (hasStrongDirectionality) 430 *hasStrongDirectionality = false; 431 return U_LEFT_TO_RIGHT; 432 } 433 434 bool containsOnlyASCII() const; 435 bool containsOnlyLatin1() const; 436 bool containsOnlyWhitespace() const { return !m_impl || m_impl->containsOnlyWhitespace(); } 437 438 // Hash table deleted values, which are only constructed and never copied or destroyed. 439 String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { } 440 bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); } 441 442#ifndef NDEBUG 443 WTF_EXPORT_STRING_API void show() const; 444#endif 445 446 // Workaround for a compiler bug. Use operator[] instead. 447 UChar characterAt(unsigned index) const 448 { 449 if (!m_impl || index >= m_impl->length()) 450 return 0; 451 return (*m_impl)[index]; 452 } 453 454private: 455 template <typename CharacterType> 456 void removeInternal(const CharacterType*, unsigned, int); 457 458 template <typename CharacterType> 459 void appendInternal(CharacterType); 460 461 RefPtr<StringImpl> m_impl; 462}; 463 464inline bool operator==(const String& a, const String& b) { return equal(a.impl(), b.impl()); } 465inline bool operator==(const String& a, const LChar* b) { return equal(a.impl(), b); } 466inline bool operator==(const String& a, const char* b) { return equal(a.impl(), reinterpret_cast<const LChar*>(b)); } 467inline bool operator==(const LChar* a, const String& b) { return equal(a, b.impl()); } 468inline bool operator==(const char* a, const String& b) { return equal(reinterpret_cast<const LChar*>(a), b.impl()); } 469template<size_t inlineCapacity> 470inline bool operator==(const Vector<char, inlineCapacity>& a, const String& b) { return equal(b.impl(), a.data(), a.size()); } 471template<size_t inlineCapacity> 472inline bool operator==(const String& a, const Vector<char, inlineCapacity>& b) { return b == a; } 473 474 475inline bool operator!=(const String& a, const String& b) { return !equal(a.impl(), b.impl()); } 476inline bool operator!=(const String& a, const LChar* b) { return !equal(a.impl(), b); } 477inline bool operator!=(const String& a, const char* b) { return !equal(a.impl(), reinterpret_cast<const LChar*>(b)); } 478inline bool operator!=(const LChar* a, const String& b) { return !equal(a, b.impl()); } 479inline bool operator!=(const char* a, const String& b) { return !equal(reinterpret_cast<const LChar*>(a), b.impl()); } 480template<size_t inlineCapacity> 481inline bool operator!=(const Vector<char, inlineCapacity>& a, const String& b) { return !(a == b); } 482template<size_t inlineCapacity> 483inline bool operator!=(const String& a, const Vector<char, inlineCapacity>& b) { return b != a; } 484 485inline bool equalIgnoringCase(const String& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); } 486inline bool equalIgnoringCase(const String& a, const LChar* b) { return equalIgnoringCase(a.impl(), b); } 487inline bool equalIgnoringCase(const String& a, const char* b) { return equalIgnoringCase(a.impl(), reinterpret_cast<const LChar*>(b)); } 488inline bool equalIgnoringCase(const LChar* a, const String& b) { return equalIgnoringCase(a, b.impl()); } 489inline bool equalIgnoringCase(const char* a, const String& b) { return equalIgnoringCase(reinterpret_cast<const LChar*>(a), b.impl()); } 490 491inline bool equalPossiblyIgnoringCase(const String& a, const String& b, bool ignoreCase) 492{ 493 return ignoreCase ? equalIgnoringCase(a, b) : (a == b); 494} 495 496inline bool equalIgnoringNullity(const String& a, const String& b) { return equalIgnoringNullity(a.impl(), b.impl()); } 497 498template<size_t inlineCapacity> 499inline bool equalIgnoringNullity(const Vector<UChar, inlineCapacity>& a, const String& b) { return equalIgnoringNullity(a, b.impl()); } 500 501inline bool operator!(const String& str) { return str.isNull(); } 502 503inline void swap(String& a, String& b) { a.swap(b); } 504 505// Definitions of string operations 506 507template<size_t inlineCapacity, typename OverflowHandler> 508String::String(const Vector<UChar, inlineCapacity, OverflowHandler>& vector) 509 : m_impl(vector.size() ? StringImpl::create(vector.data(), vector.size()) : *StringImpl::empty()) 510{ 511} 512 513template<> 514inline const LChar* String::characters<LChar>() const 515{ 516 ASSERT(is8Bit()); 517 return characters8(); 518} 519 520template<> 521inline const UChar* String::characters<UChar>() const 522{ 523 ASSERT(!is8Bit()); 524 return characters16(); 525} 526 527inline bool String::containsOnlyLatin1() const 528{ 529 if (isEmpty()) 530 return true; 531 532 if (is8Bit()) 533 return true; 534 535 const UChar* characters = characters16(); 536 UChar ored = 0; 537 for (size_t i = 0; i < m_impl->length(); ++i) 538 ored |= characters[i]; 539 return !(ored & 0xFF00); 540} 541 542 543#ifdef __OBJC__ 544// This is for situations in WebKit where the long standing behavior has been 545// "nil if empty", so we try to maintain longstanding behavior for the sake of 546// entrenched clients 547inline NSString* nsStringNilIfEmpty(const String& str) { return str.isEmpty() ? nil : (NSString*)str; } 548#endif 549 550inline bool String::containsOnlyASCII() const 551{ 552 if (isEmpty()) 553 return true; 554 555 if (is8Bit()) 556 return charactersAreAllASCII(characters8(), m_impl->length()); 557 558 return charactersAreAllASCII(characters16(), m_impl->length()); 559} 560 561WTF_EXPORT_STRING_API int codePointCompare(const String&, const String&); 562 563inline bool codePointCompareLessThan(const String& a, const String& b) 564{ 565 return codePointCompare(a.impl(), b.impl()) < 0; 566} 567 568template<typename CharacterType> 569inline void appendNumber(Vector<CharacterType>& vector, unsigned char number) 570{ 571 int numberLength = number > 99 ? 3 : (number > 9 ? 2 : 1); 572 size_t vectorSize = vector.size(); 573 vector.grow(vectorSize + numberLength); 574 575 switch (numberLength) { 576 case 3: 577 vector[vectorSize + 2] = number % 10 + '0'; 578 number /= 10; 579 FALLTHROUGH; 580 581 case 2: 582 vector[vectorSize + 1] = number % 10 + '0'; 583 number /= 10; 584 FALLTHROUGH; 585 586 case 1: 587 vector[vectorSize] = number % 10 + '0'; 588 } 589} 590 591template<bool isSpecialCharacter(UChar), typename CharacterType> 592inline bool isAllSpecialCharacters(const CharacterType* characters, size_t length) 593{ 594 for (size_t i = 0; i < length; ++i) { 595 if (!isSpecialCharacter(characters[i])) 596 return false; 597 } 598 return true; 599} 600 601template<bool isSpecialCharacter(UChar)> 602inline bool String::isAllSpecialCharacters() const 603{ 604 size_t len = length(); 605 606 if (!len) 607 return true; 608 609 if (is8Bit()) 610 return WTF::isAllSpecialCharacters<isSpecialCharacter, LChar>(characters8(), len); 611 return WTF::isAllSpecialCharacters<isSpecialCharacter, UChar>(characters16(), len); 612} 613 614// StringHash is the default hash for String 615template<typename T> struct DefaultHash; 616template<> struct DefaultHash<String> { 617 typedef StringHash Hash; 618}; 619 620template <> struct VectorTraits<String> : SimpleClassVectorTraits { }; 621 622class ASCIILiteral { 623public: 624 explicit ASCIILiteral(const char* characters) : m_characters(characters) { } 625 operator const char*() { return m_characters; } 626 627private: 628 const char* m_characters; 629}; 630 631// Shared global empty string. 632WTF_EXPORT_STRING_API const String& emptyString(); 633 634} 635 636using WTF::CString; 637using WTF::KeepTrailingZeros; 638using WTF::String; 639using WTF::emptyString; 640using WTF::appendNumber; 641using WTF::charactersAreAllASCII; 642using WTF::charactersToIntStrict; 643using WTF::charactersToUIntStrict; 644using WTF::charactersToInt64Strict; 645using WTF::charactersToUInt64Strict; 646using WTF::charactersToIntPtrStrict; 647using WTF::charactersToInt; 648using WTF::charactersToUInt; 649using WTF::charactersToInt64; 650using WTF::charactersToUInt64; 651using WTF::charactersToIntPtr; 652using WTF::charactersToDouble; 653using WTF::charactersToFloat; 654using WTF::equal; 655using WTF::equalIgnoringCase; 656using WTF::find; 657using WTF::isAllSpecialCharacters; 658using WTF::isSpaceOrNewline; 659using WTF::reverseFind; 660using WTF::ASCIILiteral; 661 662#include <wtf/text/AtomicString.h> 663#endif 664