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