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