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