1 /* 2 * (C) 1999 Lars Knoll (knoll@kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. 4 * All rights reserved. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_WTF_STRING_H_ 24 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_WTF_STRING_H_ 25 26 // This file would be called String.h, but that conflicts with <string.h> 27 // on systems without case-sensitive file systems. 28 29 #include <iosfwd> 30 #include "base/containers/span.h" 31 #include "build/build_config.h" 32 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" 33 #include "third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h" 34 #include "third_party/blink/renderer/platform/wtf/text/string_impl.h" 35 #include "third_party/blink/renderer/platform/wtf/text/string_view.h" 36 #include "third_party/blink/renderer/platform/wtf/wtf_export.h" 37 #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" 38 39 #ifdef __OBJC__ 40 #include <objc/objc.h> 41 #endif 42 43 namespace WTF { 44 45 struct StringHash; 46 47 enum UTF8ConversionMode { 48 kLenientUTF8Conversion, 49 kStrictUTF8Conversion, 50 kStrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD 51 }; 52 53 #define DISPATCH_CASE_OP(caseSensitivity, op, args) \ 54 ((caseSensitivity == kTextCaseSensitive) \ 55 ? op args \ 56 : (caseSensitivity == kTextCaseASCIIInsensitive) \ 57 ? op##IgnoringASCIICase args \ 58 : op##IgnoringCase args) 59 60 // You can find documentation about this class in README.md in this directory. 61 class WTF_EXPORT String { 62 USING_FAST_MALLOC(String); 63 64 public: 65 // Construct a null string, distinguishable from an empty string. 66 String() = default; 67 68 // Construct a string with UTF-16 data. 69 String(const UChar* characters, unsigned length); 70 71 // Construct a string by copying the contents of a vector. 72 // This method will never create a null string. Vectors with size() == 0 73 // will return the empty string. 74 // NOTE: This is different from String(vector.data(), vector.size()) 75 // which will sometimes return a null string when vector.data() is null 76 // which can only occur for vectors without inline capacity. 77 // See: https://bugs.webkit.org/show_bug.cgi?id=109792 78 template <wtf_size_t inlineCapacity> 79 explicit String(const Vector<UChar, inlineCapacity>&); 80 81 // Construct a string with UTF-16 data, from a null-terminated source. 82 String(const UChar*); String(const char16_t * chars)83 String(const char16_t* chars) 84 : String(reinterpret_cast<const UChar*>(chars)) {} 85 86 // Construct a string with latin1 data. 87 String(const LChar* characters, unsigned length); 88 String(const char* characters, unsigned length); 89 90 #if defined(ARCH_CPU_64_BITS) 91 // Only define a size_t constructor if size_t is 64 bit otherwise 92 // we'd have a duplicate define. 93 String(const char* characters, size_t length); 94 #endif // defined(ARCH_CPU_64_BITS) 95 96 // Construct a string with latin1 data, from a null-terminated source. String(const LChar * characters)97 String(const LChar* characters) 98 : String(reinterpret_cast<const char*>(characters)) {} String(const char * characters)99 String(const char* characters) 100 : String(characters, characters ? strlen(characters) : 0) {} 101 102 // Construct a string referencing an existing StringImpl. String(StringImpl * impl)103 String(StringImpl* impl) : impl_(impl) {} String(scoped_refptr<StringImpl> impl)104 String(scoped_refptr<StringImpl> impl) : impl_(std::move(impl)) {} 105 106 // Copying a String is a relatively inexpensive, since the underlying data is 107 // immutable and refcounted. 108 String(const String&) = default; 109 String& operator=(const String&) = default; 110 111 String(String&&) noexcept = default; 112 String& operator=(String&&) = default; 113 swap(String & o)114 void swap(String& o) { impl_.swap(o.impl_); } 115 116 template <typename CharType> Adopt(StringBuffer<CharType> & buffer)117 static String Adopt(StringBuffer<CharType>& buffer) { 118 if (!buffer.length()) 119 return StringImpl::empty_; 120 return String(buffer.Release()); 121 } 122 123 explicit operator bool() const { return !IsNull(); } IsNull()124 bool IsNull() const { return !impl_; } IsEmpty()125 bool IsEmpty() const { return !impl_ || !impl_->length(); } 126 Impl()127 StringImpl* Impl() const { return impl_.get(); } ReleaseImpl()128 scoped_refptr<StringImpl> ReleaseImpl() { return std::move(impl_); } 129 length()130 unsigned length() const { 131 if (!impl_) 132 return 0; 133 return impl_->length(); 134 } 135 136 // Prefer Span8() and Span16() to Characters8() and Characters16(). Span8()137 base::span<const LChar> Span8() const { 138 if (!impl_) 139 return {}; 140 DCHECK(impl_->Is8Bit()); 141 return impl_->Span8(); 142 } 143 Span16()144 base::span<const UChar> Span16() const { 145 if (!impl_) 146 return {}; 147 DCHECK(!impl_->Is8Bit()); 148 return impl_->Span16(); 149 } 150 Characters8()151 const LChar* Characters8() const { 152 if (!impl_) 153 return nullptr; 154 DCHECK(impl_->Is8Bit()); 155 return impl_->Characters8(); 156 } 157 Characters16()158 const UChar* Characters16() const { 159 if (!impl_) 160 return nullptr; 161 DCHECK(!impl_->Is8Bit()); 162 return impl_->Characters16(); 163 } 164 Bytes()165 ALWAYS_INLINE const void* Bytes() const { 166 if (!impl_) 167 return nullptr; 168 return impl_->Bytes(); 169 } 170 171 // Return characters8() or characters16() depending on CharacterType. 172 template <typename CharacterType> 173 inline const CharacterType* GetCharacters() const; 174 Is8Bit()175 bool Is8Bit() const { return impl_->Is8Bit(); } 176 177 std::string Ascii() const WARN_UNUSED_RESULT; 178 std::string Latin1() const WARN_UNUSED_RESULT; 179 std::string Utf8(UTF8ConversionMode = kLenientUTF8Conversion) const 180 WARN_UNUSED_RESULT; 181 182 UChar operator[](unsigned index) const { 183 if (!impl_ || index >= impl_->length()) 184 return 0; 185 return (*impl_)[index]; 186 } 187 188 template <typename IntegerType> Number(IntegerType number)189 static String Number(IntegerType number) { 190 IntegerToStringConverter<IntegerType> converter(number); 191 return StringImpl::Create(converter.Characters8(), converter.length()); 192 } 193 194 static String Number(float) WARN_UNUSED_RESULT; 195 196 static String Number(double, unsigned precision = 6) WARN_UNUSED_RESULT; 197 198 // Number to String conversion following the ECMAScript definition. 199 static String NumberToStringECMAScript(double) WARN_UNUSED_RESULT; 200 static String NumberToStringFixedWidth(double, unsigned decimal_places) 201 WARN_UNUSED_RESULT; 202 203 // Find characters. 204 wtf_size_t find(UChar c, unsigned start = 0) const { 205 return impl_ ? impl_->Find(c, start) : kNotFound; 206 } 207 wtf_size_t find(LChar c, unsigned start = 0) const { 208 return impl_ ? impl_->Find(c, start) : kNotFound; 209 } 210 wtf_size_t find(char c, unsigned start = 0) const { 211 return find(static_cast<LChar>(c), start); 212 } 213 wtf_size_t Find(CharacterMatchFunctionPtr match_function, 214 unsigned start = 0) const { 215 return impl_ ? impl_->Find(match_function, start) : kNotFound; 216 } 217 wtf_size_t Find(base::RepeatingCallback<bool(UChar)> match_callback, 218 wtf_size_t index = 0) const; 219 220 // Find substrings. 221 wtf_size_t Find( 222 const StringView& value, 223 unsigned start = 0, 224 TextCaseSensitivity case_sensitivity = kTextCaseSensitive) const { 225 return impl_ 226 ? DISPATCH_CASE_OP(case_sensitivity, impl_->Find, (value, start)) 227 : kNotFound; 228 } 229 230 // Unicode aware case insensitive string matching. Non-ASCII characters might 231 // match to ASCII characters. This function is rarely used to implement web 232 // platform features. 233 wtf_size_t FindIgnoringCase(const StringView& value, 234 unsigned start = 0) const { 235 return impl_ ? impl_->FindIgnoringCase(value, start) : kNotFound; 236 } 237 238 // ASCII case insensitive string matching. 239 wtf_size_t FindIgnoringASCIICase(const StringView& value, 240 unsigned start = 0) const { 241 return impl_ ? impl_->FindIgnoringASCIICase(value, start) : kNotFound; 242 } 243 Contains(char c)244 bool Contains(char c) const { return find(c) != kNotFound; } 245 bool Contains( 246 const StringView& value, 247 TextCaseSensitivity case_sensitivity = kTextCaseSensitive) const { 248 return Find(value, 0, case_sensitivity) != kNotFound; 249 } 250 251 // Find the last instance of a single character or string. 252 wtf_size_t ReverseFind(UChar c, unsigned start = UINT_MAX) const { 253 return impl_ ? impl_->ReverseFind(c, start) : kNotFound; 254 } 255 wtf_size_t ReverseFind(const StringView& value, 256 unsigned start = UINT_MAX) const { 257 return impl_ ? impl_->ReverseFind(value, start) : kNotFound; 258 } 259 260 UChar32 CharacterStartingAt(unsigned) const; 261 262 bool StartsWith( 263 const StringView& prefix, 264 TextCaseSensitivity case_sensitivity = kTextCaseSensitive) const { 265 return impl_ 266 ? DISPATCH_CASE_OP(case_sensitivity, impl_->StartsWith, (prefix)) 267 : prefix.IsEmpty(); 268 } StartsWithIgnoringCase(const StringView & prefix)269 bool StartsWithIgnoringCase(const StringView& prefix) const { 270 return impl_ ? impl_->StartsWithIgnoringCase(prefix) : prefix.IsEmpty(); 271 } StartsWithIgnoringASCIICase(const StringView & prefix)272 bool StartsWithIgnoringASCIICase(const StringView& prefix) const { 273 return impl_ ? impl_->StartsWithIgnoringASCIICase(prefix) 274 : prefix.IsEmpty(); 275 } StartsWith(UChar character)276 bool StartsWith(UChar character) const { 277 return impl_ ? impl_->StartsWith(character) : false; 278 } 279 280 bool EndsWith( 281 const StringView& suffix, 282 TextCaseSensitivity case_sensitivity = kTextCaseSensitive) const { 283 return impl_ ? DISPATCH_CASE_OP(case_sensitivity, impl_->EndsWith, (suffix)) 284 : suffix.IsEmpty(); 285 } EndsWithIgnoringCase(const StringView & prefix)286 bool EndsWithIgnoringCase(const StringView& prefix) const { 287 return impl_ ? impl_->EndsWithIgnoringCase(prefix) : prefix.IsEmpty(); 288 } EndsWithIgnoringASCIICase(const StringView & prefix)289 bool EndsWithIgnoringASCIICase(const StringView& prefix) const { 290 return impl_ ? impl_->EndsWithIgnoringASCIICase(prefix) : prefix.IsEmpty(); 291 } EndsWith(UChar character)292 bool EndsWith(UChar character) const { 293 return impl_ ? impl_->EndsWith(character) : false; 294 } 295 296 // TODO(esprehn): replace strangely both modifies this String *and* return a 297 // value. It should only do one of those. Replace(UChar pattern,UChar replacement)298 String& Replace(UChar pattern, UChar replacement) { 299 if (impl_) 300 impl_ = impl_->Replace(pattern, replacement); 301 return *this; 302 } Replace(UChar pattern,const StringView & replacement)303 String& Replace(UChar pattern, const StringView& replacement) { 304 if (impl_) 305 impl_ = impl_->Replace(pattern, replacement); 306 return *this; 307 } Replace(const StringView & pattern,const StringView & replacement)308 String& Replace(const StringView& pattern, const StringView& replacement) { 309 if (impl_) 310 impl_ = impl_->Replace(pattern, replacement); 311 return *this; 312 } replace(unsigned index,unsigned length_to_replace,const StringView & replacement)313 String& replace(unsigned index, 314 unsigned length_to_replace, 315 const StringView& replacement) { 316 if (impl_) 317 impl_ = impl_->Replace(index, length_to_replace, replacement); 318 return *this; 319 } 320 Fill(UChar c)321 void Fill(UChar c) { 322 if (impl_) 323 impl_ = impl_->Fill(c); 324 } 325 326 void Ensure16Bit(); 327 328 void Truncate(unsigned length); 329 void Remove(unsigned start, unsigned length = 1); 330 331 String Substring(unsigned pos, 332 unsigned len = UINT_MAX) const WARN_UNUSED_RESULT; Left(unsigned len)333 String Left(unsigned len) const WARN_UNUSED_RESULT { 334 return Substring(0, len); 335 } Right(unsigned len)336 String Right(unsigned len) const WARN_UNUSED_RESULT { 337 return Substring(length() - len, len); 338 } 339 340 // Returns a lowercase version of the string. This function might convert 341 // non-ASCII characters to ASCII characters. For example, DeprecatedLower() 342 // for U+212A is 'k'. 343 // This function is rarely used to implement web platform features. See 344 // crbug.com/627682. 345 // This function is deprecated. We should use LowerASCII() or CaseMap. 346 String DeprecatedLower() const WARN_UNUSED_RESULT; 347 348 // Returns a lowercase version of the string. 349 // This function converts ASCII characters only. 350 String LowerASCII() const WARN_UNUSED_RESULT; 351 // Returns a uppercase version of the string. 352 // This function converts ASCII characters only. 353 String UpperASCII() const WARN_UNUSED_RESULT; 354 355 String StripWhiteSpace() const WARN_UNUSED_RESULT; 356 String StripWhiteSpace(IsWhiteSpaceFunctionPtr) const WARN_UNUSED_RESULT; 357 String SimplifyWhiteSpace(StripBehavior = kStripExtraWhiteSpace) const 358 WARN_UNUSED_RESULT; 359 String SimplifyWhiteSpace(IsWhiteSpaceFunctionPtr, 360 StripBehavior = kStripExtraWhiteSpace) const 361 WARN_UNUSED_RESULT; 362 363 String RemoveCharacters(CharacterMatchFunctionPtr) const WARN_UNUSED_RESULT; 364 template <bool isSpecialCharacter(UChar)> 365 bool IsAllSpecialCharacters() const; 366 367 // Return the string with case folded for case insensitive comparison. 368 String FoldCase() const WARN_UNUSED_RESULT; 369 370 // Takes a printf format and args and prints into a String. 371 // This function supports Latin-1 characters only. 372 PRINTF_FORMAT(1, 2) 373 static String Format(const char* format, ...) WARN_UNUSED_RESULT; 374 375 // Returns a version suitable for gtest and base/logging.*. It prepends and 376 // appends double-quotes, and escapes characters other than ASCII printables. 377 String EncodeForDebugging() const WARN_UNUSED_RESULT; 378 379 // Returns an uninitialized string. The characters needs to be written 380 // into the buffer returned in data before the returned string is used. 381 // Failure to do this will have unpredictable results. CreateUninitialized(unsigned length,UChar * & data)382 static String CreateUninitialized(unsigned length, 383 UChar*& data) WARN_UNUSED_RESULT { 384 return StringImpl::CreateUninitialized(length, data); 385 } CreateUninitialized(unsigned length,LChar * & data)386 static String CreateUninitialized(unsigned length, 387 LChar*& data) WARN_UNUSED_RESULT { 388 return StringImpl::CreateUninitialized(length, data); 389 } 390 391 void Split(const StringView& separator, 392 bool allow_empty_entries, 393 Vector<String>& result) const; Split(const StringView & separator,Vector<String> & result)394 void Split(const StringView& separator, Vector<String>& result) const { 395 Split(separator, false, result); 396 } 397 void Split(UChar separator, 398 bool allow_empty_entries, 399 Vector<String>& result) const; Split(UChar separator,Vector<String> & result)400 void Split(UChar separator, Vector<String>& result) const { 401 Split(separator, false, result); 402 } 403 404 // Copy characters out of the string. See StringImpl.h for detailed docs. CopyTo(UChar * buffer,unsigned start,unsigned max_length)405 unsigned CopyTo(UChar* buffer, unsigned start, unsigned max_length) const { 406 return impl_ ? impl_->CopyTo(buffer, start, max_length) : 0; 407 } 408 template <typename BufferType> 409 void AppendTo(BufferType&, 410 unsigned start = 0, 411 unsigned length = UINT_MAX) const; 412 template <typename BufferType> 413 void PrependTo(BufferType&, 414 unsigned start = 0, 415 unsigned length = UINT_MAX) const; 416 417 // Convert the string into a number. 418 419 // The following ToFooStrict functions accept: 420 // - leading '+' 421 // - leading Unicode whitespace 422 // - trailing Unicode whitespace 423 // - no "-0" (ToUIntStrict and ToUInt64Strict) 424 // - no out-of-range numbers which the resultant type can't represent 425 // 426 // If the input string is not acceptable, 0 is returned and |*ok| becomes 427 // |false|. 428 // 429 // We can use these functions to implement a Web Platform feature only if the 430 // input string is already valid according to the specification of the 431 // feature. 432 int ToIntStrict(bool* ok = nullptr) const; 433 unsigned ToUIntStrict(bool* ok = nullptr) const; 434 unsigned HexToUIntStrict(bool* ok) const; 435 uint64_t HexToUInt64Strict(bool* ok) const; 436 int64_t ToInt64Strict(bool* ok = nullptr) const; 437 uint64_t ToUInt64Strict(bool* ok = nullptr) const; 438 439 // The following ToFoo functions accept: 440 // - leading '+' 441 // - leading Unicode whitespace 442 // - trailing garbage 443 // - no "-0" (ToUInt and ToUInt64) 444 // - no out-of-range numbers which the resultant type can't represent 445 // 446 // If the input string is not acceptable, 0 is returned and |*ok| becomes 447 // |false|. 448 // 449 // We can use these functions to implement a Web Platform feature only if the 450 // input string is already valid according to the specification of the 451 // feature. 452 int ToInt(bool* ok = nullptr) const; 453 unsigned ToUInt(bool* ok = nullptr) const; 454 455 // These functions accepts: 456 // - leading '+' 457 // - numbers without leading zeros such as ".5" 458 // - numbers ending with "." such as "3." 459 // - scientific notation 460 // - leading whitespace (IsASCIISpace, not IsHTMLSpace) 461 // - no trailing whitespace 462 // - no trailing garbage 463 // - no numbers such as "NaN" "Infinity" 464 // 465 // A huge absolute number which a double/float can't represent is accepted, 466 // and +Infinity or -Infinity is returned. 467 // 468 // A small absolute numbers which a double/float can't represent is accepted, 469 // and 0 is returned 470 // 471 // If the input string is not acceptable, 0.0 is returned and |*ok| becomes 472 // |false|. 473 // 474 // We can use these functions to implement a Web Platform feature only if the 475 // input string is already valid according to the specification of the 476 // feature. 477 // 478 // FIXME: Like the strict functions above, these give false for "ok" when 479 // there is trailing garbage. Like the non-strict functions above, these 480 // return the value when there is trailing garbage. It would be better if 481 // these were more consistent with the above functions instead. 482 double ToDouble(bool* ok = nullptr) const; 483 float ToFloat(bool* ok = nullptr) const; 484 485 String IsolatedCopy() const WARN_UNUSED_RESULT; 486 bool IsSafeToSendToAnotherThread() const; 487 488 #ifdef __OBJC__ 489 String(NSString*); 490 491 // This conversion maps null string to "", which loses the meaning of null 492 // string, but we need this mapping because AppKit crashes when passed nil 493 // NSStrings. 494 operator NSString*() const { 495 if (!impl_) 496 return @""; 497 return *impl_; 498 } 499 #endif 500 501 static String Make8BitFrom16BitSource(const UChar*, 502 wtf_size_t) WARN_UNUSED_RESULT; 503 template <wtf_size_t inlineCapacity> 504 static WARN_UNUSED_RESULT String Make8BitFrom16BitSource(const Vector<UChar,inlineCapacity> & buffer)505 Make8BitFrom16BitSource(const Vector<UChar, inlineCapacity>& buffer) { 506 return Make8BitFrom16BitSource(buffer.data(), buffer.size()); 507 } 508 509 static String Make16BitFrom8BitSource(const LChar*, 510 wtf_size_t) WARN_UNUSED_RESULT; 511 512 // String::fromUTF8 will return a null string if 513 // the input data contains invalid UTF-8 sequences. 514 // Does not strip BOMs. 515 static String FromUTF8(const LChar*, size_t) WARN_UNUSED_RESULT; 516 static String FromUTF8(const LChar*) WARN_UNUSED_RESULT; FromUTF8(const char * s,size_t length)517 static String FromUTF8(const char* s, size_t length) WARN_UNUSED_RESULT { 518 return FromUTF8(reinterpret_cast<const LChar*>(s), length); 519 } FromUTF8(const char * s)520 static String FromUTF8(const char* s) WARN_UNUSED_RESULT { 521 return FromUTF8(reinterpret_cast<const LChar*>(s)); 522 } 523 static String FromUTF8(base::StringPiece) WARN_UNUSED_RESULT; 524 525 // Tries to convert the passed in string to UTF-8, but will fall back to 526 // Latin-1 if the string is not valid UTF-8. 527 static String FromUTF8WithLatin1Fallback(const LChar*, 528 size_t) WARN_UNUSED_RESULT; FromUTF8WithLatin1Fallback(const char * s,size_t length)529 static String FromUTF8WithLatin1Fallback(const char* s, 530 size_t length) WARN_UNUSED_RESULT { 531 return FromUTF8WithLatin1Fallback(reinterpret_cast<const LChar*>(s), 532 length); 533 } 534 ContainsOnlyASCIIOrEmpty()535 bool ContainsOnlyASCIIOrEmpty() const { 536 return !impl_ || impl_->ContainsOnlyASCIIOrEmpty(); 537 } 538 bool ContainsOnlyLatin1OrEmpty() const; ContainsOnlyWhitespaceOrEmpty()539 bool ContainsOnlyWhitespaceOrEmpty() const { 540 return !impl_ || impl_->ContainsOnlyWhitespaceOrEmpty(); 541 } 542 CharactersSizeInBytes()543 size_t CharactersSizeInBytes() const { 544 return impl_ ? impl_->CharactersSizeInBytes() : 0; 545 } 546 547 #ifndef NDEBUG 548 // For use in the debugger. 549 void Show() const; 550 #endif 551 552 private: 553 friend struct HashTraits<String>; 554 555 scoped_refptr<StringImpl> impl_; 556 }; 557 558 #undef DISPATCH_CASE_OP 559 560 inline bool operator==(const String& a, const String& b) { 561 // We don't use equalStringView here since we want the isAtomic() fast path 562 // inside WTF::equal. 563 return Equal(a.Impl(), b.Impl()); 564 } 565 inline bool operator==(const String& a, const char* b) { 566 return EqualStringView(a, b); 567 } 568 inline bool operator==(const char* a, const String& b) { 569 return b == a; 570 } 571 572 inline bool operator!=(const String& a, const String& b) { 573 return !(a == b); 574 } 575 inline bool operator!=(const String& a, const char* b) { 576 return !(a == b); 577 } 578 inline bool operator!=(const char* a, const String& b) { 579 return !(a == b); 580 } 581 582 inline bool EqualIgnoringNullity(const String& a, const String& b) { 583 return EqualIgnoringNullity(a.Impl(), b.Impl()); 584 } 585 586 template <wtf_size_t inlineCapacity> 587 inline bool EqualIgnoringNullity(const Vector<UChar, inlineCapacity>& a, 588 const String& b) { 589 return EqualIgnoringNullity(a, b.Impl()); 590 } 591 592 inline void swap(String& a, String& b) { 593 a.swap(b); 594 } 595 596 // Definitions of string operations 597 598 template <wtf_size_t inlineCapacity> 599 String::String(const Vector<UChar, inlineCapacity>& vector) 600 : impl_(vector.size() ? StringImpl::Create(vector.data(), vector.size()) 601 : StringImpl::empty_) {} 602 603 template <> 604 inline const LChar* String::GetCharacters<LChar>() const { 605 DCHECK(Is8Bit()); 606 return Characters8(); 607 } 608 609 template <> 610 inline const UChar* String::GetCharacters<UChar>() const { 611 DCHECK(!Is8Bit()); 612 return Characters16(); 613 } 614 615 inline bool String::ContainsOnlyLatin1OrEmpty() const { 616 if (IsEmpty()) 617 return true; 618 619 if (Is8Bit()) 620 return true; 621 622 const UChar* characters = Characters16(); 623 UChar ored = 0; 624 for (wtf_size_t i = 0; i < impl_->length(); ++i) 625 ored |= characters[i]; 626 return !(ored & 0xFF00); 627 } 628 629 #ifdef __OBJC__ 630 // This is for situations in WebKit where the long standing behavior has been 631 // "nil if empty", so we try to maintain longstanding behavior for the sake of 632 // entrenched clients 633 inline NSString* NsStringNilIfEmpty(const String& str) { 634 return str.IsEmpty() ? nil : (NSString*)str; 635 } 636 #endif 637 638 // Compare strings using code units, matching Javascript string ordering. See 639 // https://infra.spec.whatwg.org/#code-unit-less-than. 640 WTF_EXPORT int CodeUnitCompare(const String&, const String&); 641 642 inline bool CodeUnitCompareLessThan(const String& a, const String& b) { 643 return CodeUnitCompare(a.Impl(), b.Impl()) < 0; 644 } 645 646 WTF_EXPORT int CodeUnitCompareIgnoringASCIICase(const String&, const char*); 647 648 template <bool isSpecialCharacter(UChar)> 649 inline bool String::IsAllSpecialCharacters() const { 650 return StringView(*this).IsAllSpecialCharacters<isSpecialCharacter>(); 651 } 652 653 template <typename BufferType> 654 void String::AppendTo(BufferType& result, 655 unsigned position, 656 unsigned length) const { 657 if (!impl_) 658 return; 659 impl_->AppendTo(result, position, length); 660 } 661 662 template <typename BufferType> 663 void String::PrependTo(BufferType& result, 664 unsigned position, 665 unsigned length) const { 666 if (!impl_) 667 return; 668 impl_->PrependTo(result, position, length); 669 } 670 671 // StringHash is the default hash for String 672 template <typename T> 673 struct DefaultHash; 674 template <> 675 struct DefaultHash<String> { 676 typedef StringHash Hash; 677 }; 678 679 // Shared global empty string. 680 WTF_EXPORT extern const String& g_empty_string; 681 WTF_EXPORT extern const String& g_empty_string16_bit; 682 WTF_EXPORT extern const String& g_xmlns_with_colon; 683 684 // Pretty printer for gtest and base/logging.*. It prepends and appends 685 // double-quotes, and escapes characters other than ASCII printables. 686 WTF_EXPORT std::ostream& operator<<(std::ostream&, const String&); 687 688 inline StringView::StringView(const String& string, 689 unsigned offset, 690 unsigned length) 691 : StringView(string.Impl(), offset, length) {} 692 inline StringView::StringView(const String& string, unsigned offset) 693 : StringView(string.Impl(), offset) {} 694 inline StringView::StringView(const String& string) 695 : StringView(string.Impl()) {} 696 697 } // namespace WTF 698 699 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(String) 700 701 using WTF::kStrictUTF8Conversion; 702 using WTF::kStrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD; 703 using WTF::String; 704 using WTF::g_empty_string; 705 using WTF::g_empty_string16_bit; 706 using WTF::Equal; 707 using WTF::Find; 708 using WTF::IsSpaceOrNewline; 709 710 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" 711 #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_WTF_STRING_H_ 712