Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2001 Dirk Mueller ( mueller (at) kde.org )
      5  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
      6  * Copyright (C) 2006 Andrew Wellington (proton (at) wiretapped.net)
      7  *
      8  * This library is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU Library General Public
     10  * License as published by the Free Software Foundation; either
     11  * version 2 of the License, or (at your option) any later version.
     12  *
     13  * This library is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16  * Library General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU Library General Public License
     19  * along with this library; see the file COPYING.LIB.  If not, write to
     20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     21  * Boston, MA 02110-1301, USA.
     22  *
     23  */
     24 
     25 #include "config.h"
     26 #include "wtf/text/StringImpl.h"
     27 
     28 #include "wtf/StdLibExtras.h"
     29 #include "wtf/text/AtomicString.h"
     30 #include "wtf/text/StringBuffer.h"
     31 #include "wtf/text/StringHash.h"
     32 #include "wtf/unicode/CharacterNames.h"
     33 
     34 #ifdef STRING_STATS
     35 #include "wtf/DataLog.h"
     36 #include "wtf/MainThread.h"
     37 #include "wtf/ProcessID.h"
     38 #include "wtf/RefCounted.h"
     39 #include <unistd.h>
     40 #endif
     41 
     42 using namespace std;
     43 
     44 namespace WTF {
     45 
     46 using namespace Unicode;
     47 
     48 COMPILE_ASSERT(sizeof(StringImpl) == 3 * sizeof(int), StringImpl_should_stay_small);
     49 
     50 #ifdef STRING_STATS
     51 
     52 static Mutex& statsMutex()
     53 {
     54     DEFINE_STATIC_LOCAL(Mutex, mutex, ());
     55     return mutex;
     56 }
     57 
     58 static HashSet<void*>& liveStrings()
     59 {
     60     // Notice that we can't use HashSet<StringImpl*> because then HashSet would dedup identical strings.
     61     DEFINE_STATIC_LOCAL(HashSet<void*>, strings, ());
     62     return strings;
     63 }
     64 
     65 void addStringForStats(StringImpl* string)
     66 {
     67     MutexLocker locker(statsMutex());
     68     liveStrings().add(string);
     69 }
     70 
     71 void removeStringForStats(StringImpl* string)
     72 {
     73     MutexLocker locker(statsMutex());
     74     liveStrings().remove(string);
     75 }
     76 
     77 static void fillWithSnippet(const StringImpl* string, Vector<char>& snippet)
     78 {
     79     const unsigned kMaxSnippetLength = 64;
     80     snippet.clear();
     81 
     82     size_t expectedLength = std::min(string->length(), kMaxSnippetLength);
     83     if (expectedLength == kMaxSnippetLength)
     84         expectedLength += 3; // For the "...".
     85     ++expectedLength; // For the terminating '\0'.
     86     snippet.reserveCapacity(expectedLength);
     87 
     88     size_t i;
     89     for (i = 0; i < string->length() && i < kMaxSnippetLength; ++i) {
     90         UChar c = (*string)[i];
     91         if (isASCIIPrintable(c))
     92             snippet.append(c);
     93         else
     94             snippet.append('?');
     95     }
     96     if (i < string->length()) {
     97         snippet.append('.');
     98         snippet.append('.');
     99         snippet.append('.');
    100     }
    101     snippet.append('\0');
    102 }
    103 
    104 static bool isUnnecessarilyWide(const StringImpl* string)
    105 {
    106     if (string->is8Bit())
    107         return false;
    108     UChar c = 0;
    109     for (unsigned i = 0; i < string->length(); ++i)
    110         c |= (*string)[i] >> 8;
    111     return !c;
    112 }
    113 
    114 class PerStringStats : public RefCounted<PerStringStats> {
    115 public:
    116     static PassRefPtr<PerStringStats> create()
    117     {
    118         return adoptRef(new PerStringStats);
    119     }
    120 
    121     void add(const StringImpl* string)
    122     {
    123         ++m_numberOfCopies;
    124         if (!m_length) {
    125             m_length = string->length();
    126             fillWithSnippet(string, m_snippet);
    127         }
    128         if (string->isAtomic())
    129             ++m_numberOfAtomicCopies;
    130         if (isUnnecessarilyWide(string))
    131             m_unnecessarilyWide = true;
    132     }
    133 
    134     size_t totalCharacters() const
    135     {
    136         return m_numberOfCopies * m_length;
    137     }
    138 
    139     void print()
    140     {
    141         const char* status = "ok";
    142         if (m_unnecessarilyWide)
    143             status = "16";
    144         dataLogF("%8u copies (%s) of length %8u %s\n", m_numberOfCopies, status, m_length, m_snippet.data());
    145     }
    146 
    147     bool m_unnecessarilyWide;
    148     unsigned m_numberOfCopies;
    149     unsigned m_length;
    150     unsigned m_numberOfAtomicCopies;
    151     Vector<char> m_snippet;
    152 
    153 private:
    154     PerStringStats()
    155         : m_unnecessarilyWide(false)
    156         , m_numberOfCopies(0)
    157         , m_length(0)
    158         , m_numberOfAtomicCopies(0)
    159     {
    160     }
    161 };
    162 
    163 bool operator<(const RefPtr<PerStringStats>& a, const RefPtr<PerStringStats>& b)
    164 {
    165     if (a->m_unnecessarilyWide != b->m_unnecessarilyWide)
    166         return !a->m_unnecessarilyWide && b->m_unnecessarilyWide;
    167     if (a->totalCharacters() != b->totalCharacters())
    168         return a->totalCharacters() < b->totalCharacters();
    169     if (a->m_numberOfCopies != b->m_numberOfCopies)
    170         return a->m_numberOfCopies < b->m_numberOfCopies;
    171     if (a->m_length != b->m_length)
    172         return a->m_length < b->m_length;
    173     return a->m_numberOfAtomicCopies < b->m_numberOfAtomicCopies;
    174 }
    175 
    176 static void printLiveStringStats(void*)
    177 {
    178     MutexLocker locker(statsMutex());
    179     HashSet<void*>& strings = liveStrings();
    180 
    181     HashMap<StringImpl*, RefPtr<PerStringStats> > stats;
    182     for (HashSet<void*>::iterator iter = strings.begin(); iter != strings.end(); ++iter) {
    183         StringImpl* string = static_cast<StringImpl*>(*iter);
    184         HashMap<StringImpl*, RefPtr<PerStringStats> >::iterator entry = stats.find(string);
    185         RefPtr<PerStringStats> value = entry == stats.end() ? RefPtr<PerStringStats>(PerStringStats::create()) : entry->value;
    186         value->add(string);
    187         stats.set(string, value.release());
    188     }
    189 
    190     Vector<RefPtr<PerStringStats> > all;
    191     for (HashMap<StringImpl*, RefPtr<PerStringStats> >::iterator iter = stats.begin(); iter != stats.end(); ++iter)
    192         all.append(iter->value);
    193 
    194     std::sort(all.begin(), all.end());
    195     std::reverse(all.begin(), all.end());
    196     for (size_t i = 0; i < 20 && i < all.size(); ++i)
    197         all[i]->print();
    198 }
    199 
    200 StringStats StringImpl::m_stringStats;
    201 
    202 unsigned StringStats::s_stringRemovesTillPrintStats = StringStats::s_printStringStatsFrequency;
    203 
    204 void StringStats::removeString(StringImpl* string)
    205 {
    206     unsigned length = string->length();
    207     --m_totalNumberStrings;
    208 
    209     if (string->is8Bit()) {
    210         --m_number8BitStrings;
    211         m_total8BitData -= length;
    212     } else {
    213         --m_number16BitStrings;
    214         m_total16BitData -= length;
    215     }
    216 
    217     if (!--s_stringRemovesTillPrintStats) {
    218         s_stringRemovesTillPrintStats = s_printStringStatsFrequency;
    219         printStats();
    220     }
    221 }
    222 
    223 void StringStats::printStats()
    224 {
    225     dataLogF("String stats for process id %d:\n", getCurrentProcessID());
    226 
    227     unsigned long long totalNumberCharacters = m_total8BitData + m_total16BitData;
    228     double percent8Bit = m_totalNumberStrings ? ((double)m_number8BitStrings * 100) / (double)m_totalNumberStrings : 0.0;
    229     double average8bitLength = m_number8BitStrings ? (double)m_total8BitData / (double)m_number8BitStrings : 0.0;
    230     dataLogF("%8u (%5.2f%%) 8 bit        %12llu chars  %12llu bytes  avg length %6.1f\n", m_number8BitStrings, percent8Bit, m_total8BitData, m_total8BitData, average8bitLength);
    231 
    232     double percent16Bit = m_totalNumberStrings ? ((double)m_number16BitStrings * 100) / (double)m_totalNumberStrings : 0.0;
    233     double average16bitLength = m_number16BitStrings ? (double)m_total16BitData / (double)m_number16BitStrings : 0.0;
    234     dataLogF("%8u (%5.2f%%) 16 bit       %12llu chars  %12llu bytes  avg length %6.1f\n", m_number16BitStrings, percent16Bit, m_total16BitData, m_total16BitData * 2, average16bitLength);
    235 
    236     double averageLength = m_totalNumberStrings ? (double)totalNumberCharacters / (double)m_totalNumberStrings : 0.0;
    237     unsigned long long totalDataBytes = m_total8BitData + m_total16BitData * 2;
    238     dataLogF("%8u Total                 %12llu chars  %12llu bytes  avg length %6.1f\n", m_totalNumberStrings, totalNumberCharacters, totalDataBytes, averageLength);
    239     unsigned long long totalSavedBytes = m_total8BitData;
    240     double percentSavings = totalSavedBytes ? ((double)totalSavedBytes * 100) / (double)(totalDataBytes + totalSavedBytes) : 0.0;
    241     dataLogF("         Total savings %12llu bytes (%5.2f%%)\n", totalSavedBytes, percentSavings);
    242 
    243     unsigned totalOverhead = m_totalNumberStrings * sizeof(StringImpl);
    244     double overheadPercent = (double)totalOverhead / (double)totalDataBytes * 100;
    245     dataLogF("         StringImpl overheader: %8u (%5.2f%%)\n", totalOverhead, overheadPercent);
    246 
    247     callOnMainThread(printLiveStringStats, 0);
    248 }
    249 #endif
    250 
    251 
    252 StringImpl::~StringImpl()
    253 {
    254     ASSERT(!isStatic());
    255 
    256     STRING_STATS_REMOVE_STRING(this);
    257 
    258     if (isAtomic())
    259         AtomicString::remove(this);
    260 }
    261 
    262 PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data)
    263 {
    264     if (!length) {
    265         data = 0;
    266         return empty();
    267     }
    268 
    269     // Allocate a single buffer large enough to contain the StringImpl
    270     // struct as well as the data which it contains. This removes one
    271     // heap allocation from this call.
    272     RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar)));
    273     size_t size = sizeof(StringImpl) + length * sizeof(LChar);
    274     StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
    275 
    276     data = reinterpret_cast<LChar*>(string + 1);
    277     return adoptRef(new (NotNull, string) StringImpl(length, Force8BitConstructor));
    278 }
    279 
    280 PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data)
    281 {
    282     if (!length) {
    283         data = 0;
    284         return empty();
    285     }
    286 
    287     // Allocate a single buffer large enough to contain the StringImpl
    288     // struct as well as the data which it contains. This removes one
    289     // heap allocation from this call.
    290     RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar)));
    291     size_t size = sizeof(StringImpl) + length * sizeof(UChar);
    292     StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
    293 
    294     data = reinterpret_cast<UChar*>(string + 1);
    295     return adoptRef(new (NotNull, string) StringImpl(length));
    296 }
    297 
    298 PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, LChar*& data)
    299 {
    300     ASSERT(originalString->is8Bit());
    301     ASSERT(originalString->hasOneRef());
    302 
    303     if (!length) {
    304         data = 0;
    305         return empty();
    306     }
    307 
    308     // Same as createUninitialized() except here we use fastRealloc.
    309     RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar)));
    310     size_t size = sizeof(StringImpl) + length * sizeof(LChar);
    311     originalString->~StringImpl();
    312     StringImpl* string = static_cast<StringImpl*>(fastRealloc(originalString.leakRef(), size));
    313 
    314     data = reinterpret_cast<LChar*>(string + 1);
    315     return adoptRef(new (NotNull, string) StringImpl(length, Force8BitConstructor));
    316 }
    317 
    318 PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, UChar*& data)
    319 {
    320     ASSERT(!originalString->is8Bit());
    321     ASSERT(originalString->hasOneRef());
    322 
    323     if (!length) {
    324         data = 0;
    325         return empty();
    326     }
    327 
    328     // Same as createUninitialized() except here we use fastRealloc.
    329     RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar)));
    330     size_t size = sizeof(StringImpl) + length * sizeof(UChar);
    331     originalString->~StringImpl();
    332     StringImpl* string = static_cast<StringImpl*>(fastRealloc(originalString.leakRef(), size));
    333 
    334     data = reinterpret_cast<UChar*>(string + 1);
    335     return adoptRef(new (NotNull, string) StringImpl(length));
    336 }
    337 
    338 StringImpl* StringImpl::createStatic(const char* string, unsigned length, unsigned hash)
    339 {
    340     ASSERT(string);
    341     ASSERT(length);
    342 
    343     // Allocate a single buffer large enough to contain the StringImpl
    344     // struct as well as the data which it contains. This removes one
    345     // heap allocation from this call.
    346     RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar)));
    347     size_t size = sizeof(StringImpl) + length * sizeof(LChar);
    348     StringImpl* impl = static_cast<StringImpl*>(fastMalloc(size));
    349 
    350     LChar* data = reinterpret_cast<LChar*>(impl + 1);
    351     impl = new (NotNull, impl) StringImpl(length, hash, StaticString);
    352     memcpy(data, string, length * sizeof(LChar));
    353 #ifndef NDEBUG
    354     impl->assertHashIsCorrect();
    355 #endif
    356     return impl;
    357 }
    358 
    359 PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length)
    360 {
    361     if (!characters || !length)
    362         return empty();
    363 
    364     UChar* data;
    365     RefPtr<StringImpl> string = createUninitialized(length, data);
    366     memcpy(data, characters, length * sizeof(UChar));
    367     return string.release();
    368 }
    369 
    370 PassRefPtr<StringImpl> StringImpl::create(const LChar* characters, unsigned length)
    371 {
    372     if (!characters || !length)
    373         return empty();
    374 
    375     LChar* data;
    376     RefPtr<StringImpl> string = createUninitialized(length, data);
    377     memcpy(data, characters, length * sizeof(LChar));
    378     return string.release();
    379 }
    380 
    381 PassRefPtr<StringImpl> StringImpl::create8BitIfPossible(const UChar* characters, unsigned length)
    382 {
    383     if (!characters || !length)
    384         return empty();
    385 
    386     LChar* data;
    387     RefPtr<StringImpl> string = createUninitialized(length, data);
    388 
    389     for (size_t i = 0; i < length; ++i) {
    390         if (characters[i] & 0xff00)
    391             return create(characters, length);
    392         data[i] = static_cast<LChar>(characters[i]);
    393     }
    394 
    395     return string.release();
    396 }
    397 
    398 PassRefPtr<StringImpl> StringImpl::create(const LChar* string)
    399 {
    400     if (!string)
    401         return empty();
    402     size_t length = strlen(reinterpret_cast<const char*>(string));
    403     RELEASE_ASSERT(length <= numeric_limits<unsigned>::max());
    404     return create(string, length);
    405 }
    406 
    407 bool StringImpl::containsOnlyWhitespace()
    408 {
    409     // FIXME: The definition of whitespace here includes a number of characters
    410     // that are not whitespace from the point of view of RenderText; I wonder if
    411     // that's a problem in practice.
    412     if (is8Bit()) {
    413         for (unsigned i = 0; i < m_length; ++i) {
    414             UChar c = characters8()[i];
    415             if (!isASCIISpace(c))
    416                 return false;
    417         }
    418 
    419         return true;
    420     }
    421 
    422     for (unsigned i = 0; i < m_length; ++i) {
    423         UChar c = characters16()[i];
    424         if (!isASCIISpace(c))
    425             return false;
    426     }
    427     return true;
    428 }
    429 
    430 PassRefPtr<StringImpl> StringImpl::substring(unsigned start, unsigned length)
    431 {
    432     if (start >= m_length)
    433         return empty();
    434     unsigned maxLength = m_length - start;
    435     if (length >= maxLength) {
    436         if (!start)
    437             return this;
    438         length = maxLength;
    439     }
    440     if (is8Bit())
    441         return create(characters8() + start, length);
    442 
    443     return create(characters16() + start, length);
    444 }
    445 
    446 UChar32 StringImpl::characterStartingAt(unsigned i)
    447 {
    448     if (is8Bit())
    449         return characters8()[i];
    450     if (U16_IS_SINGLE(characters16()[i]))
    451         return characters16()[i];
    452     if (i + 1 < m_length && U16_IS_LEAD(characters16()[i]) && U16_IS_TRAIL(characters16()[i + 1]))
    453         return U16_GET_SUPPLEMENTARY(characters16()[i], characters16()[i + 1]);
    454     return 0;
    455 }
    456 
    457 PassRefPtr<StringImpl> StringImpl::lower()
    458 {
    459     // Note: This is a hot function in the Dromaeo benchmark, specifically the
    460     // no-op code path up through the first 'return' statement.
    461 
    462     // First scan the string for uppercase and non-ASCII characters:
    463     bool noUpper = true;
    464     UChar ored = 0;
    465     if (is8Bit()) {
    466         const LChar* end = characters8() + m_length;
    467         for (const LChar* chp = characters8(); chp != end; ++chp) {
    468             if (UNLIKELY(isASCIIUpper(*chp)))
    469                 noUpper = false;
    470             ored |= *chp;
    471         }
    472         // Nothing to do if the string is all ASCII with no uppercase.
    473         if (noUpper && !(ored & ~0x7F))
    474             return this;
    475 
    476         RELEASE_ASSERT(m_length <= static_cast<unsigned>(numeric_limits<int32_t>::max()));
    477         int32_t length = m_length;
    478 
    479         LChar* data8;
    480         RefPtr<StringImpl> newImpl = createUninitialized(length, data8);
    481 
    482         if (!(ored & ~0x7F)) {
    483             for (int32_t i = 0; i < length; ++i)
    484                 data8[i] = toASCIILower(characters8()[i]);
    485 
    486             return newImpl.release();
    487         }
    488 
    489         // Do a slower implementation for cases that include non-ASCII Latin-1 characters.
    490         for (int32_t i = 0; i < length; ++i)
    491             data8[i] = static_cast<LChar>(Unicode::toLower(characters8()[i]));
    492 
    493         return newImpl.release();
    494     }
    495 
    496     const UChar* end = characters16() + m_length;
    497     for (const UChar* chp = characters16(); chp != end; ++chp) {
    498         if (UNLIKELY(isASCIIUpper(*chp)))
    499             noUpper = false;
    500         ored |= *chp;
    501     }
    502     // Nothing to do if the string is all ASCII with no uppercase.
    503     if (noUpper && !(ored & ~0x7F))
    504         return this;
    505 
    506     RELEASE_ASSERT(m_length <= static_cast<unsigned>(numeric_limits<int32_t>::max()));
    507     int32_t length = m_length;
    508 
    509     if (!(ored & ~0x7F)) {
    510         UChar* data16;
    511         RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16);
    512 
    513         for (int32_t i = 0; i < length; ++i) {
    514             UChar c = characters16()[i];
    515             data16[i] = toASCIILower(c);
    516         }
    517         return newImpl.release();
    518     }
    519 
    520     // Do a slower implementation for cases that include non-ASCII characters.
    521     UChar* data16;
    522     RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16);
    523 
    524     bool error;
    525     int32_t realLength = Unicode::toLower(data16, length, characters16(), m_length, &error);
    526     if (!error && realLength == length)
    527         return newImpl.release();
    528 
    529     newImpl = createUninitialized(realLength, data16);
    530     Unicode::toLower(data16, realLength, characters16(), m_length, &error);
    531     if (error)
    532         return this;
    533     return newImpl.release();
    534 }
    535 
    536 PassRefPtr<StringImpl> StringImpl::upper()
    537 {
    538     // This function could be optimized for no-op cases the way lower() is,
    539     // but in empirical testing, few actual calls to upper() are no-ops, so
    540     // it wouldn't be worth the extra time for pre-scanning.
    541 
    542     RELEASE_ASSERT(m_length <= static_cast<unsigned>(numeric_limits<int32_t>::max()));
    543     int32_t length = m_length;
    544 
    545     if (is8Bit()) {
    546         LChar* data8;
    547         RefPtr<StringImpl> newImpl = createUninitialized(m_length, data8);
    548 
    549         // Do a faster loop for the case where all the characters are ASCII.
    550         LChar ored = 0;
    551         for (int i = 0; i < length; ++i) {
    552             LChar c = characters8()[i];
    553             ored |= c;
    554             data8[i] = toASCIIUpper(c);
    555         }
    556         if (!(ored & ~0x7F))
    557             return newImpl.release();
    558 
    559         // Do a slower implementation for cases that include non-ASCII Latin-1 characters.
    560         int numberSharpSCharacters = 0;
    561 
    562         // There are two special cases.
    563         //  1. latin-1 characters when converted to upper case are 16 bit characters.
    564         //  2. Lower case sharp-S converts to "SS" (two characters)
    565         for (int32_t i = 0; i < length; ++i) {
    566             LChar c = characters8()[i];
    567             if (UNLIKELY(c == smallLetterSharpS))
    568                 ++numberSharpSCharacters;
    569             UChar upper = Unicode::toUpper(c);
    570             if (UNLIKELY(upper > 0xff)) {
    571                 // Since this upper-cased character does not fit in an 8-bit string, we need to take the 16-bit path.
    572                 goto upconvert;
    573             }
    574             data8[i] = static_cast<LChar>(upper);
    575         }
    576 
    577         if (!numberSharpSCharacters)
    578             return newImpl.release();
    579 
    580         // We have numberSSCharacters sharp-s characters, but none of the other special characters.
    581         newImpl = createUninitialized(m_length + numberSharpSCharacters, data8);
    582 
    583         LChar* dest = data8;
    584 
    585         for (int32_t i = 0; i < length; ++i) {
    586             LChar c = characters8()[i];
    587             if (c == smallLetterSharpS) {
    588                 *dest++ = 'S';
    589                 *dest++ = 'S';
    590             } else
    591                 *dest++ = static_cast<LChar>(Unicode::toUpper(c));
    592         }
    593 
    594         return newImpl.release();
    595     }
    596 
    597 upconvert:
    598     const UChar* source16 = 0;
    599     RefPtr<StringImpl> upconverted;
    600     if (is8Bit()) {
    601         upconverted = String::make16BitFrom8BitSource(characters8(), m_length).impl();
    602         source16 = upconverted->characters16();
    603     } else {
    604         source16 = characters16();
    605     }
    606 
    607     UChar* data16;
    608     RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16);
    609 
    610     // Do a faster loop for the case where all the characters are ASCII.
    611     UChar ored = 0;
    612     for (int i = 0; i < length; ++i) {
    613         UChar c = source16[i];
    614         ored |= c;
    615         data16[i] = toASCIIUpper(c);
    616     }
    617     if (!(ored & ~0x7F))
    618         return newImpl.release();
    619 
    620     // Do a slower implementation for cases that include non-ASCII characters.
    621     bool error;
    622     newImpl = createUninitialized(m_length, data16);
    623     int32_t realLength = Unicode::toUpper(data16, length, source16, m_length, &error);
    624     if (!error && realLength == length)
    625         return newImpl;
    626     newImpl = createUninitialized(realLength, data16);
    627     Unicode::toUpper(data16, realLength, source16, m_length, &error);
    628     if (error)
    629         return this;
    630     return newImpl.release();
    631 }
    632 
    633 PassRefPtr<StringImpl> StringImpl::fill(UChar character)
    634 {
    635     if (!m_length)
    636         return this;
    637 
    638     if (!(character & ~0x7F)) {
    639         LChar* data;
    640         RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
    641         for (unsigned i = 0; i < m_length; ++i)
    642             data[i] = character;
    643         return newImpl.release();
    644     }
    645     UChar* data;
    646     RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
    647     for (unsigned i = 0; i < m_length; ++i)
    648         data[i] = character;
    649     return newImpl.release();
    650 }
    651 
    652 PassRefPtr<StringImpl> StringImpl::foldCase()
    653 {
    654     RELEASE_ASSERT(m_length <= static_cast<unsigned>(numeric_limits<int32_t>::max()));
    655     int32_t length = m_length;
    656 
    657     if (is8Bit()) {
    658         // Do a faster loop for the case where all the characters are ASCII.
    659         LChar* data;
    660         RefPtr <StringImpl>newImpl = createUninitialized(m_length, data);
    661         LChar ored = 0;
    662 
    663         for (int32_t i = 0; i < length; ++i) {
    664             LChar c = characters8()[i];
    665             data[i] = toASCIILower(c);
    666             ored |= c;
    667         }
    668 
    669         if (!(ored & ~0x7F))
    670             return newImpl.release();
    671 
    672         // Do a slower implementation for cases that include non-ASCII Latin-1 characters.
    673         for (int32_t i = 0; i < length; ++i)
    674             data[i] = static_cast<LChar>(Unicode::toLower(characters8()[i]));
    675 
    676         return newImpl.release();
    677     }
    678 
    679     // Do a faster loop for the case where all the characters are ASCII.
    680     UChar* data;
    681     RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
    682     UChar ored = 0;
    683     for (int32_t i = 0; i < length; ++i) {
    684         UChar c = characters16()[i];
    685         ored |= c;
    686         data[i] = toASCIILower(c);
    687     }
    688     if (!(ored & ~0x7F))
    689         return newImpl.release();
    690 
    691     // Do a slower implementation for cases that include non-ASCII characters.
    692     bool error;
    693     int32_t realLength = Unicode::foldCase(data, length, characters16(), m_length, &error);
    694     if (!error && realLength == length)
    695         return newImpl.release();
    696     newImpl = createUninitialized(realLength, data);
    697     Unicode::foldCase(data, realLength, characters16(), m_length, &error);
    698     if (error)
    699         return this;
    700     return newImpl.release();
    701 }
    702 
    703 template <class UCharPredicate>
    704 inline PassRefPtr<StringImpl> StringImpl::stripMatchedCharacters(UCharPredicate predicate)
    705 {
    706     if (!m_length)
    707         return empty();
    708 
    709     unsigned start = 0;
    710     unsigned end = m_length - 1;
    711 
    712     // skip white space from start
    713     while (start <= end && predicate(is8Bit() ? characters8()[start] : characters16()[start]))
    714         ++start;
    715 
    716     // only white space
    717     if (start > end)
    718         return empty();
    719 
    720     // skip white space from end
    721     while (end && predicate(is8Bit() ? characters8()[end] : characters16()[end]))
    722         --end;
    723 
    724     if (!start && end == m_length - 1)
    725         return this;
    726     if (is8Bit())
    727         return create(characters8() + start, end + 1 - start);
    728     return create(characters16() + start, end + 1 - start);
    729 }
    730 
    731 class UCharPredicate {
    732 public:
    733     inline UCharPredicate(CharacterMatchFunctionPtr function): m_function(function) { }
    734 
    735     inline bool operator()(UChar ch) const
    736     {
    737         return m_function(ch);
    738     }
    739 
    740 private:
    741     const CharacterMatchFunctionPtr m_function;
    742 };
    743 
    744 class SpaceOrNewlinePredicate {
    745 public:
    746     inline bool operator()(UChar ch) const
    747     {
    748         return isSpaceOrNewline(ch);
    749     }
    750 };
    751 
    752 PassRefPtr<StringImpl> StringImpl::stripWhiteSpace()
    753 {
    754     return stripMatchedCharacters(SpaceOrNewlinePredicate());
    755 }
    756 
    757 PassRefPtr<StringImpl> StringImpl::stripWhiteSpace(IsWhiteSpaceFunctionPtr isWhiteSpace)
    758 {
    759     return stripMatchedCharacters(UCharPredicate(isWhiteSpace));
    760 }
    761 
    762 template <typename CharType>
    763 ALWAYS_INLINE PassRefPtr<StringImpl> StringImpl::removeCharacters(const CharType* characters, CharacterMatchFunctionPtr findMatch)
    764 {
    765     const CharType* from = characters;
    766     const CharType* fromend = from + m_length;
    767 
    768     // Assume the common case will not remove any characters
    769     while (from != fromend && !findMatch(*from))
    770         ++from;
    771     if (from == fromend)
    772         return this;
    773 
    774     StringBuffer<CharType> data(m_length);
    775     CharType* to = data.characters();
    776     unsigned outc = from - characters;
    777 
    778     if (outc)
    779         memcpy(to, characters, outc * sizeof(CharType));
    780 
    781     while (true) {
    782         while (from != fromend && findMatch(*from))
    783             ++from;
    784         while (from != fromend && !findMatch(*from))
    785             to[outc++] = *from++;
    786         if (from == fromend)
    787             break;
    788     }
    789 
    790     data.shrink(outc);
    791 
    792     return data.release();
    793 }
    794 
    795 PassRefPtr<StringImpl> StringImpl::removeCharacters(CharacterMatchFunctionPtr findMatch)
    796 {
    797     if (is8Bit())
    798         return removeCharacters(characters8(), findMatch);
    799     return removeCharacters(characters16(), findMatch);
    800 }
    801 
    802 template <typename CharType, class UCharPredicate>
    803 inline PassRefPtr<StringImpl> StringImpl::simplifyMatchedCharactersToSpace(UCharPredicate predicate)
    804 {
    805     StringBuffer<CharType> data(m_length);
    806 
    807     const CharType* from = getCharacters<CharType>();
    808     const CharType* fromend = from + m_length;
    809     int outc = 0;
    810     bool changedToSpace = false;
    811 
    812     CharType* to = data.characters();
    813 
    814     while (true) {
    815         while (from != fromend && predicate(*from)) {
    816             if (*from != ' ')
    817                 changedToSpace = true;
    818             ++from;
    819         }
    820         while (from != fromend && !predicate(*from))
    821             to[outc++] = *from++;
    822         if (from != fromend)
    823             to[outc++] = ' ';
    824         else
    825             break;
    826     }
    827 
    828     if (outc > 0 && to[outc - 1] == ' ')
    829         --outc;
    830 
    831     if (static_cast<unsigned>(outc) == m_length && !changedToSpace)
    832         return this;
    833 
    834     data.shrink(outc);
    835 
    836     return data.release();
    837 }
    838 
    839 PassRefPtr<StringImpl> StringImpl::simplifyWhiteSpace()
    840 {
    841     if (is8Bit())
    842         return StringImpl::simplifyMatchedCharactersToSpace<LChar>(SpaceOrNewlinePredicate());
    843     return StringImpl::simplifyMatchedCharactersToSpace<UChar>(SpaceOrNewlinePredicate());
    844 }
    845 
    846 PassRefPtr<StringImpl> StringImpl::simplifyWhiteSpace(IsWhiteSpaceFunctionPtr isWhiteSpace)
    847 {
    848     if (is8Bit())
    849         return StringImpl::simplifyMatchedCharactersToSpace<LChar>(UCharPredicate(isWhiteSpace));
    850     return StringImpl::simplifyMatchedCharactersToSpace<UChar>(UCharPredicate(isWhiteSpace));
    851 }
    852 
    853 int StringImpl::toIntStrict(bool* ok, int base)
    854 {
    855     if (is8Bit())
    856         return charactersToIntStrict(characters8(), m_length, ok, base);
    857     return charactersToIntStrict(characters16(), m_length, ok, base);
    858 }
    859 
    860 unsigned StringImpl::toUIntStrict(bool* ok, int base)
    861 {
    862     if (is8Bit())
    863         return charactersToUIntStrict(characters8(), m_length, ok, base);
    864     return charactersToUIntStrict(characters16(), m_length, ok, base);
    865 }
    866 
    867 int64_t StringImpl::toInt64Strict(bool* ok, int base)
    868 {
    869     if (is8Bit())
    870         return charactersToInt64Strict(characters8(), m_length, ok, base);
    871     return charactersToInt64Strict(characters16(), m_length, ok, base);
    872 }
    873 
    874 uint64_t StringImpl::toUInt64Strict(bool* ok, int base)
    875 {
    876     if (is8Bit())
    877         return charactersToUInt64Strict(characters8(), m_length, ok, base);
    878     return charactersToUInt64Strict(characters16(), m_length, ok, base);
    879 }
    880 
    881 intptr_t StringImpl::toIntPtrStrict(bool* ok, int base)
    882 {
    883     if (is8Bit())
    884         return charactersToIntPtrStrict(characters8(), m_length, ok, base);
    885     return charactersToIntPtrStrict(characters16(), m_length, ok, base);
    886 }
    887 
    888 int StringImpl::toInt(bool* ok)
    889 {
    890     if (is8Bit())
    891         return charactersToInt(characters8(), m_length, ok);
    892     return charactersToInt(characters16(), m_length, ok);
    893 }
    894 
    895 unsigned StringImpl::toUInt(bool* ok)
    896 {
    897     if (is8Bit())
    898         return charactersToUInt(characters8(), m_length, ok);
    899     return charactersToUInt(characters16(), m_length, ok);
    900 }
    901 
    902 int64_t StringImpl::toInt64(bool* ok)
    903 {
    904     if (is8Bit())
    905         return charactersToInt64(characters8(), m_length, ok);
    906     return charactersToInt64(characters16(), m_length, ok);
    907 }
    908 
    909 uint64_t StringImpl::toUInt64(bool* ok)
    910 {
    911     if (is8Bit())
    912         return charactersToUInt64(characters8(), m_length, ok);
    913     return charactersToUInt64(characters16(), m_length, ok);
    914 }
    915 
    916 intptr_t StringImpl::toIntPtr(bool* ok)
    917 {
    918     if (is8Bit())
    919         return charactersToIntPtr(characters8(), m_length, ok);
    920     return charactersToIntPtr(characters16(), m_length, ok);
    921 }
    922 
    923 double StringImpl::toDouble(bool* ok)
    924 {
    925     if (is8Bit())
    926         return charactersToDouble(characters8(), m_length, ok);
    927     return charactersToDouble(characters16(), m_length, ok);
    928 }
    929 
    930 float StringImpl::toFloat(bool* ok)
    931 {
    932     if (is8Bit())
    933         return charactersToFloat(characters8(), m_length, ok);
    934     return charactersToFloat(characters16(), m_length, ok);
    935 }
    936 
    937 bool equalIgnoringCase(const LChar* a, const LChar* b, unsigned length)
    938 {
    939     while (length--) {
    940         LChar bc = *b++;
    941         if (foldCase(*a++) != foldCase(bc))
    942             return false;
    943     }
    944     return true;
    945 }
    946 
    947 bool equalIgnoringCase(const UChar* a, const LChar* b, unsigned length)
    948 {
    949     while (length--) {
    950         LChar bc = *b++;
    951         if (foldCase(*a++) != foldCase(bc))
    952             return false;
    953     }
    954     return true;
    955 }
    956 
    957 size_t StringImpl::find(CharacterMatchFunctionPtr matchFunction, unsigned start)
    958 {
    959     if (is8Bit())
    960         return WTF::find(characters8(), m_length, matchFunction, start);
    961     return WTF::find(characters16(), m_length, matchFunction, start);
    962 }
    963 
    964 size_t StringImpl::find(const LChar* matchString, unsigned index)
    965 {
    966     // Check for null or empty string to match against
    967     if (!matchString)
    968         return notFound;
    969     size_t matchStringLength = strlen(reinterpret_cast<const char*>(matchString));
    970     RELEASE_ASSERT(matchStringLength <= numeric_limits<unsigned>::max());
    971     unsigned matchLength = matchStringLength;
    972     if (!matchLength)
    973         return min(index, length());
    974 
    975     // Optimization 1: fast case for strings of length 1.
    976     if (matchLength == 1)
    977         return WTF::find(characters16(), length(), *matchString, index);
    978 
    979     // Check index & matchLength are in range.
    980     if (index > length())
    981         return notFound;
    982     unsigned searchLength = length() - index;
    983     if (matchLength > searchLength)
    984         return notFound;
    985     // delta is the number of additional times to test; delta == 0 means test only once.
    986     unsigned delta = searchLength - matchLength;
    987 
    988     const UChar* searchCharacters = characters16() + index;
    989 
    990     // Optimization 2: keep a running hash of the strings,
    991     // only call equal if the hashes match.
    992     unsigned searchHash = 0;
    993     unsigned matchHash = 0;
    994     for (unsigned i = 0; i < matchLength; ++i) {
    995         searchHash += searchCharacters[i];
    996         matchHash += matchString[i];
    997     }
    998 
    999     unsigned i = 0;
   1000     // keep looping until we match
   1001     while (searchHash != matchHash || !equal(searchCharacters + i, matchString, matchLength)) {
   1002         if (i == delta)
   1003             return notFound;
   1004         searchHash += searchCharacters[i + matchLength];
   1005         searchHash -= searchCharacters[i];
   1006         ++i;
   1007     }
   1008     return index + i;
   1009 }
   1010 
   1011 template<typename CharType>
   1012 ALWAYS_INLINE size_t findIgnoringCaseInternal(const CharType* searchCharacters, const LChar* matchString, unsigned index, unsigned searchLength, unsigned matchLength)
   1013 {
   1014     // delta is the number of additional times to test; delta == 0 means test only once.
   1015     unsigned delta = searchLength - matchLength;
   1016 
   1017     unsigned i = 0;
   1018     while (!equalIgnoringCase(searchCharacters + i, matchString, matchLength)) {
   1019         if (i == delta)
   1020             return notFound;
   1021         ++i;
   1022     }
   1023     return index + i;
   1024 }
   1025 
   1026 size_t StringImpl::findIgnoringCase(const LChar* matchString, unsigned index)
   1027 {
   1028     // Check for null or empty string to match against
   1029     if (!matchString)
   1030         return notFound;
   1031     size_t matchStringLength = strlen(reinterpret_cast<const char*>(matchString));
   1032     RELEASE_ASSERT(matchStringLength <= numeric_limits<unsigned>::max());
   1033     unsigned matchLength = matchStringLength;
   1034     if (!matchLength)
   1035         return min(index, length());
   1036 
   1037     // Check index & matchLength are in range.
   1038     if (index > length())
   1039         return notFound;
   1040     unsigned searchLength = length() - index;
   1041     if (matchLength > searchLength)
   1042         return notFound;
   1043 
   1044     if (is8Bit())
   1045         return findIgnoringCaseInternal(characters8() + index, matchString, index, searchLength, matchLength);
   1046     return findIgnoringCaseInternal(characters16() + index, matchString, index, searchLength, matchLength);
   1047 }
   1048 
   1049 template <typename SearchCharacterType, typename MatchCharacterType>
   1050 ALWAYS_INLINE static size_t findInternal(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned searchLength, unsigned matchLength)
   1051 {
   1052     // Optimization: keep a running hash of the strings,
   1053     // only call equal() if the hashes match.
   1054 
   1055     // delta is the number of additional times to test; delta == 0 means test only once.
   1056     unsigned delta = searchLength - matchLength;
   1057 
   1058     unsigned searchHash = 0;
   1059     unsigned matchHash = 0;
   1060 
   1061     for (unsigned i = 0; i < matchLength; ++i) {
   1062         searchHash += searchCharacters[i];
   1063         matchHash += matchCharacters[i];
   1064     }
   1065 
   1066     unsigned i = 0;
   1067     // keep looping until we match
   1068     while (searchHash != matchHash || !equal(searchCharacters + i, matchCharacters, matchLength)) {
   1069         if (i == delta)
   1070             return notFound;
   1071         searchHash += searchCharacters[i + matchLength];
   1072         searchHash -= searchCharacters[i];
   1073         ++i;
   1074     }
   1075     return index + i;
   1076 }
   1077 
   1078 size_t StringImpl::find(StringImpl* matchString)
   1079 {
   1080     // Check for null string to match against
   1081     if (UNLIKELY(!matchString))
   1082         return notFound;
   1083     unsigned matchLength = matchString->length();
   1084 
   1085     // Optimization 1: fast case for strings of length 1.
   1086     if (matchLength == 1) {
   1087         if (is8Bit()) {
   1088             if (matchString->is8Bit())
   1089                 return WTF::find(characters8(), length(), matchString->characters8()[0]);
   1090             return WTF::find(characters8(), length(), matchString->characters16()[0]);
   1091         }
   1092         if (matchString->is8Bit())
   1093             return WTF::find(characters16(), length(), matchString->characters8()[0]);
   1094         return WTF::find(characters16(), length(), matchString->characters16()[0]);
   1095     }
   1096 
   1097     // Check matchLength is in range.
   1098     if (matchLength > length())
   1099         return notFound;
   1100 
   1101     // Check for empty string to match against
   1102     if (UNLIKELY(!matchLength))
   1103         return 0;
   1104 
   1105     if (is8Bit()) {
   1106         if (matchString->is8Bit())
   1107             return findInternal(characters8(), matchString->characters8(), 0, length(), matchLength);
   1108         return findInternal(characters8(), matchString->characters16(), 0, length(), matchLength);
   1109     }
   1110 
   1111     if (matchString->is8Bit())
   1112         return findInternal(characters16(), matchString->characters8(), 0, length(), matchLength);
   1113 
   1114     return findInternal(characters16(), matchString->characters16(), 0, length(), matchLength);
   1115 }
   1116 
   1117 size_t StringImpl::find(StringImpl* matchString, unsigned index)
   1118 {
   1119     // Check for null or empty string to match against
   1120     if (UNLIKELY(!matchString))
   1121         return notFound;
   1122 
   1123     unsigned matchLength = matchString->length();
   1124 
   1125     // Optimization 1: fast case for strings of length 1.
   1126     if (matchLength == 1) {
   1127         if (is8Bit())
   1128             return WTF::find(characters8(), length(), (*matchString)[0], index);
   1129         return WTF::find(characters16(), length(), (*matchString)[0], index);
   1130     }
   1131 
   1132     if (UNLIKELY(!matchLength))
   1133         return min(index, length());
   1134 
   1135     // Check index & matchLength are in range.
   1136     if (index > length())
   1137         return notFound;
   1138     unsigned searchLength = length() - index;
   1139     if (matchLength > searchLength)
   1140         return notFound;
   1141 
   1142     if (is8Bit()) {
   1143         if (matchString->is8Bit())
   1144             return findInternal(characters8() + index, matchString->characters8(), index, searchLength, matchLength);
   1145         return findInternal(characters8() + index, matchString->characters16(), index, searchLength, matchLength);
   1146     }
   1147 
   1148     if (matchString->is8Bit())
   1149         return findInternal(characters16() + index, matchString->characters8(), index, searchLength, matchLength);
   1150 
   1151     return findInternal(characters16() + index, matchString->characters16(), index, searchLength, matchLength);
   1152 }
   1153 
   1154 template <typename SearchCharacterType, typename MatchCharacterType>
   1155 ALWAYS_INLINE static size_t findIgnoringCaseInner(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned searchLength, unsigned matchLength)
   1156 {
   1157     // delta is the number of additional times to test; delta == 0 means test only once.
   1158     unsigned delta = searchLength - matchLength;
   1159 
   1160     unsigned i = 0;
   1161     // keep looping until we match
   1162     while (!equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength)) {
   1163         if (i == delta)
   1164             return notFound;
   1165         ++i;
   1166     }
   1167     return index + i;
   1168 }
   1169 
   1170 size_t StringImpl::findIgnoringCase(StringImpl* matchString, unsigned index)
   1171 {
   1172     // Check for null or empty string to match against
   1173     if (!matchString)
   1174         return notFound;
   1175     unsigned matchLength = matchString->length();
   1176     if (!matchLength)
   1177         return min(index, length());
   1178 
   1179     // Check index & matchLength are in range.
   1180     if (index > length())
   1181         return notFound;
   1182     unsigned searchLength = length() - index;
   1183     if (matchLength > searchLength)
   1184         return notFound;
   1185 
   1186     if (is8Bit()) {
   1187         if (matchString->is8Bit())
   1188             return findIgnoringCaseInner(characters8() + index, matchString->characters8(), index, searchLength, matchLength);
   1189         return findIgnoringCaseInner(characters8() + index, matchString->characters16(), index, searchLength, matchLength);
   1190     }
   1191 
   1192     if (matchString->is8Bit())
   1193         return findIgnoringCaseInner(characters16() + index, matchString->characters8(), index, searchLength, matchLength);
   1194 
   1195     return findIgnoringCaseInner(characters16() + index, matchString->characters16(), index, searchLength, matchLength);
   1196 }
   1197 
   1198 size_t StringImpl::findNextLineStart(unsigned index)
   1199 {
   1200     if (is8Bit())
   1201         return WTF::findNextLineStart(characters8(), m_length, index);
   1202     return WTF::findNextLineStart(characters16(), m_length, index);
   1203 }
   1204 
   1205 size_t StringImpl::count(LChar c) const
   1206 {
   1207     int count = 0;
   1208     if (is8Bit()) {
   1209         for (size_t i = 0; i < m_length; ++i)
   1210             count += characters8()[i] == c;
   1211     } else {
   1212         for (size_t i = 0; i < m_length; ++i)
   1213             count += characters16()[i] == c;
   1214     }
   1215     return count;
   1216 }
   1217 
   1218 size_t StringImpl::reverseFind(UChar c, unsigned index)
   1219 {
   1220     if (is8Bit())
   1221         return WTF::reverseFind(characters8(), m_length, c, index);
   1222     return WTF::reverseFind(characters16(), m_length, c, index);
   1223 }
   1224 
   1225 template <typename SearchCharacterType, typename MatchCharacterType>
   1226 ALWAYS_INLINE static size_t reverseFindInner(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned length, unsigned matchLength)
   1227 {
   1228     // Optimization: keep a running hash of the strings,
   1229     // only call equal if the hashes match.
   1230 
   1231     // delta is the number of additional times to test; delta == 0 means test only once.
   1232     unsigned delta = min(index, length - matchLength);
   1233 
   1234     unsigned searchHash = 0;
   1235     unsigned matchHash = 0;
   1236     for (unsigned i = 0; i < matchLength; ++i) {
   1237         searchHash += searchCharacters[delta + i];
   1238         matchHash += matchCharacters[i];
   1239     }
   1240 
   1241     // keep looping until we match
   1242     while (searchHash != matchHash || !equal(searchCharacters + delta, matchCharacters, matchLength)) {
   1243         if (!delta)
   1244             return notFound;
   1245         --delta;
   1246         searchHash -= searchCharacters[delta + matchLength];
   1247         searchHash += searchCharacters[delta];
   1248     }
   1249     return delta;
   1250 }
   1251 
   1252 size_t StringImpl::reverseFind(StringImpl* matchString, unsigned index)
   1253 {
   1254     // Check for null or empty string to match against
   1255     if (!matchString)
   1256         return notFound;
   1257     unsigned matchLength = matchString->length();
   1258     unsigned ourLength = length();
   1259     if (!matchLength)
   1260         return min(index, ourLength);
   1261 
   1262     // Optimization 1: fast case for strings of length 1.
   1263     if (matchLength == 1) {
   1264         if (is8Bit())
   1265             return WTF::reverseFind(characters8(), ourLength, (*matchString)[0], index);
   1266         return WTF::reverseFind(characters16(), ourLength, (*matchString)[0], index);
   1267     }
   1268 
   1269     // Check index & matchLength are in range.
   1270     if (matchLength > ourLength)
   1271         return notFound;
   1272 
   1273     if (is8Bit()) {
   1274         if (matchString->is8Bit())
   1275             return reverseFindInner(characters8(), matchString->characters8(), index, ourLength, matchLength);
   1276         return reverseFindInner(characters8(), matchString->characters16(), index, ourLength, matchLength);
   1277     }
   1278 
   1279     if (matchString->is8Bit())
   1280         return reverseFindInner(characters16(), matchString->characters8(), index, ourLength, matchLength);
   1281 
   1282     return reverseFindInner(characters16(), matchString->characters16(), index, ourLength, matchLength);
   1283 }
   1284 
   1285 template <typename SearchCharacterType, typename MatchCharacterType>
   1286 ALWAYS_INLINE static size_t reverseFindIgnoringCaseInner(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned length, unsigned matchLength)
   1287 {
   1288     // delta is the number of additional times to test; delta == 0 means test only once.
   1289     unsigned delta = min(index, length - matchLength);
   1290 
   1291     // keep looping until we match
   1292     while (!equalIgnoringCase(searchCharacters + delta, matchCharacters, matchLength)) {
   1293         if (!delta)
   1294             return notFound;
   1295         --delta;
   1296     }
   1297     return delta;
   1298 }
   1299 
   1300 size_t StringImpl::reverseFindIgnoringCase(StringImpl* matchString, unsigned index)
   1301 {
   1302     // Check for null or empty string to match against
   1303     if (!matchString)
   1304         return notFound;
   1305     unsigned matchLength = matchString->length();
   1306     unsigned ourLength = length();
   1307     if (!matchLength)
   1308         return min(index, ourLength);
   1309 
   1310     // Check index & matchLength are in range.
   1311     if (matchLength > ourLength)
   1312         return notFound;
   1313 
   1314     if (is8Bit()) {
   1315         if (matchString->is8Bit())
   1316             return reverseFindIgnoringCaseInner(characters8(), matchString->characters8(), index, ourLength, matchLength);
   1317         return reverseFindIgnoringCaseInner(characters8(), matchString->characters16(), index, ourLength, matchLength);
   1318     }
   1319 
   1320     if (matchString->is8Bit())
   1321         return reverseFindIgnoringCaseInner(characters16(), matchString->characters8(), index, ourLength, matchLength);
   1322 
   1323     return reverseFindIgnoringCaseInner(characters16(), matchString->characters16(), index, ourLength, matchLength);
   1324 }
   1325 
   1326 ALWAYS_INLINE static bool equalInner(const StringImpl* stringImpl, unsigned startOffset, const char* matchString, unsigned matchLength, bool caseSensitive)
   1327 {
   1328     ASSERT(stringImpl);
   1329     ASSERT(matchLength <= stringImpl->length());
   1330     ASSERT(startOffset + matchLength <= stringImpl->length());
   1331 
   1332     if (caseSensitive) {
   1333         if (stringImpl->is8Bit())
   1334             return equal(stringImpl->characters8() + startOffset, reinterpret_cast<const LChar*>(matchString), matchLength);
   1335         return equal(stringImpl->characters16() + startOffset, reinterpret_cast<const LChar*>(matchString), matchLength);
   1336     }
   1337     if (stringImpl->is8Bit())
   1338         return equalIgnoringCase(stringImpl->characters8() + startOffset, reinterpret_cast<const LChar*>(matchString), matchLength);
   1339     return equalIgnoringCase(stringImpl->characters16() + startOffset, reinterpret_cast<const LChar*>(matchString), matchLength);
   1340 }
   1341 
   1342 bool StringImpl::startsWith(UChar character) const
   1343 {
   1344     return m_length && (*this)[0] == character;
   1345 }
   1346 
   1347 bool StringImpl::startsWith(const char* matchString, unsigned matchLength, bool caseSensitive) const
   1348 {
   1349     ASSERT(matchLength);
   1350     if (matchLength > length())
   1351         return false;
   1352     return equalInner(this, 0, matchString, matchLength, caseSensitive);
   1353 }
   1354 
   1355 bool StringImpl::endsWith(StringImpl* matchString, bool caseSensitive)
   1356 {
   1357     ASSERT(matchString);
   1358     if (m_length >= matchString->m_length) {
   1359         unsigned start = m_length - matchString->m_length;
   1360         return (caseSensitive ? find(matchString, start) : findIgnoringCase(matchString, start)) == start;
   1361     }
   1362     return false;
   1363 }
   1364 
   1365 bool StringImpl::endsWith(UChar character) const
   1366 {
   1367     return m_length && (*this)[m_length - 1] == character;
   1368 }
   1369 
   1370 bool StringImpl::endsWith(const char* matchString, unsigned matchLength, bool caseSensitive) const
   1371 {
   1372     ASSERT(matchLength);
   1373     if (matchLength > length())
   1374         return false;
   1375     unsigned startOffset = length() - matchLength;
   1376     return equalInner(this, startOffset, matchString, matchLength, caseSensitive);
   1377 }
   1378 
   1379 PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC)
   1380 {
   1381     if (oldC == newC)
   1382         return this;
   1383     unsigned i;
   1384     for (i = 0; i != m_length; ++i) {
   1385         UChar c = is8Bit() ? characters8()[i] : characters16()[i];
   1386         if (c == oldC)
   1387             break;
   1388     }
   1389     if (i == m_length)
   1390         return this;
   1391 
   1392     if (is8Bit()) {
   1393         if (oldC > 0xff)
   1394             // Looking for a 16 bit char in an 8 bit string, we're done.
   1395             return this;
   1396 
   1397         if (newC <= 0xff) {
   1398             LChar* data;
   1399             LChar oldChar = static_cast<LChar>(oldC);
   1400             LChar newChar = static_cast<LChar>(newC);
   1401 
   1402             RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
   1403 
   1404             for (i = 0; i != m_length; ++i) {
   1405                 LChar ch = characters8()[i];
   1406                 if (ch == oldChar)
   1407                     ch = newChar;
   1408                 data[i] = ch;
   1409             }
   1410             return newImpl.release();
   1411         }
   1412 
   1413         // There is the possibility we need to up convert from 8 to 16 bit,
   1414         // create a 16 bit string for the result.
   1415         UChar* data;
   1416         RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
   1417 
   1418         for (i = 0; i != m_length; ++i) {
   1419             UChar ch = characters8()[i];
   1420             if (ch == oldC)
   1421                 ch = newC;
   1422             data[i] = ch;
   1423         }
   1424 
   1425         return newImpl.release();
   1426     }
   1427 
   1428     UChar* data;
   1429     RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
   1430 
   1431     for (i = 0; i != m_length; ++i) {
   1432         UChar ch = characters16()[i];
   1433         if (ch == oldC)
   1434             ch = newC;
   1435         data[i] = ch;
   1436     }
   1437     return newImpl.release();
   1438 }
   1439 
   1440 PassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToReplace, StringImpl* str)
   1441 {
   1442     position = min(position, length());
   1443     lengthToReplace = min(lengthToReplace, length() - position);
   1444     unsigned lengthToInsert = str ? str->length() : 0;
   1445     if (!lengthToReplace && !lengthToInsert)
   1446         return this;
   1447 
   1448     RELEASE_ASSERT((length() - lengthToReplace) < (numeric_limits<unsigned>::max() - lengthToInsert));
   1449 
   1450     if (is8Bit() && (!str || str->is8Bit())) {
   1451         LChar* data;
   1452         RefPtr<StringImpl> newImpl =
   1453         createUninitialized(length() - lengthToReplace + lengthToInsert, data);
   1454         memcpy(data, characters8(), position * sizeof(LChar));
   1455         if (str)
   1456             memcpy(data + position, str->characters8(), lengthToInsert * sizeof(LChar));
   1457         memcpy(data + position + lengthToInsert, characters8() + position + lengthToReplace,
   1458                (length() - position - lengthToReplace) * sizeof(LChar));
   1459         return newImpl.release();
   1460     }
   1461     UChar* data;
   1462     RefPtr<StringImpl> newImpl =
   1463         createUninitialized(length() - lengthToReplace + lengthToInsert, data);
   1464     if (is8Bit())
   1465         for (unsigned i = 0; i < position; ++i)
   1466             data[i] = characters8()[i];
   1467     else
   1468         memcpy(data, characters16(), position * sizeof(UChar));
   1469     if (str) {
   1470         if (str->is8Bit())
   1471             for (unsigned i = 0; i < lengthToInsert; ++i)
   1472                 data[i + position] = str->characters8()[i];
   1473         else
   1474             memcpy(data + position, str->characters16(), lengthToInsert * sizeof(UChar));
   1475     }
   1476     if (is8Bit()) {
   1477         for (unsigned i = 0; i < length() - position - lengthToReplace; ++i)
   1478             data[i + position + lengthToInsert] = characters8()[i + position + lengthToReplace];
   1479     } else {
   1480         memcpy(data + position + lengthToInsert, characters16() + position + lengthToReplace,
   1481             (length() - position - lengthToReplace) * sizeof(UChar));
   1482     }
   1483     return newImpl.release();
   1484 }
   1485 
   1486 PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacement)
   1487 {
   1488     if (!replacement)
   1489         return this;
   1490 
   1491     if (replacement->is8Bit())
   1492         return replace(pattern, replacement->characters8(), replacement->length());
   1493 
   1494     return replace(pattern, replacement->characters16(), replacement->length());
   1495 }
   1496 
   1497 PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, const LChar* replacement, unsigned repStrLength)
   1498 {
   1499     ASSERT(replacement);
   1500 
   1501     size_t srcSegmentStart = 0;
   1502     unsigned matchCount = 0;
   1503 
   1504     // Count the matches.
   1505     while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) {
   1506         ++matchCount;
   1507         ++srcSegmentStart;
   1508     }
   1509 
   1510     // If we have 0 matches then we don't have to do any more work.
   1511     if (!matchCount)
   1512         return this;
   1513 
   1514     RELEASE_ASSERT(!repStrLength || matchCount <= numeric_limits<unsigned>::max() / repStrLength);
   1515 
   1516     unsigned replaceSize = matchCount * repStrLength;
   1517     unsigned newSize = m_length - matchCount;
   1518     RELEASE_ASSERT(newSize < (numeric_limits<unsigned>::max() - replaceSize));
   1519 
   1520     newSize += replaceSize;
   1521 
   1522     // Construct the new data.
   1523     size_t srcSegmentEnd;
   1524     unsigned srcSegmentLength;
   1525     srcSegmentStart = 0;
   1526     unsigned dstOffset = 0;
   1527 
   1528     if (is8Bit()) {
   1529         LChar* data;
   1530         RefPtr<StringImpl> newImpl = createUninitialized(newSize, data);
   1531 
   1532         while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) {
   1533             srcSegmentLength = srcSegmentEnd - srcSegmentStart;
   1534             memcpy(data + dstOffset, characters8() + srcSegmentStart, srcSegmentLength * sizeof(LChar));
   1535             dstOffset += srcSegmentLength;
   1536             memcpy(data + dstOffset, replacement, repStrLength * sizeof(LChar));
   1537             dstOffset += repStrLength;
   1538             srcSegmentStart = srcSegmentEnd + 1;
   1539         }
   1540 
   1541         srcSegmentLength = m_length - srcSegmentStart;
   1542         memcpy(data + dstOffset, characters8() + srcSegmentStart, srcSegmentLength * sizeof(LChar));
   1543 
   1544         ASSERT(dstOffset + srcSegmentLength == newImpl->length());
   1545 
   1546         return newImpl.release();
   1547     }
   1548 
   1549     UChar* data;
   1550     RefPtr<StringImpl> newImpl = createUninitialized(newSize, data);
   1551 
   1552     while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) {
   1553         srcSegmentLength = srcSegmentEnd - srcSegmentStart;
   1554         memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar));
   1555 
   1556         dstOffset += srcSegmentLength;
   1557         for (unsigned i = 0; i < repStrLength; ++i)
   1558             data[i + dstOffset] = replacement[i];
   1559 
   1560         dstOffset += repStrLength;
   1561         srcSegmentStart = srcSegmentEnd + 1;
   1562     }
   1563 
   1564     srcSegmentLength = m_length - srcSegmentStart;
   1565     memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar));
   1566 
   1567     ASSERT(dstOffset + srcSegmentLength == newImpl->length());
   1568 
   1569     return newImpl.release();
   1570 }
   1571 
   1572 PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, const UChar* replacement, unsigned repStrLength)
   1573 {
   1574     ASSERT(replacement);
   1575 
   1576     size_t srcSegmentStart = 0;
   1577     unsigned matchCount = 0;
   1578 
   1579     // Count the matches.
   1580     while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) {
   1581         ++matchCount;
   1582         ++srcSegmentStart;
   1583     }
   1584 
   1585     // If we have 0 matches then we don't have to do any more work.
   1586     if (!matchCount)
   1587         return this;
   1588 
   1589     RELEASE_ASSERT(!repStrLength || matchCount <= numeric_limits<unsigned>::max() / repStrLength);
   1590 
   1591     unsigned replaceSize = matchCount * repStrLength;
   1592     unsigned newSize = m_length - matchCount;
   1593     RELEASE_ASSERT(newSize < (numeric_limits<unsigned>::max() - replaceSize));
   1594 
   1595     newSize += replaceSize;
   1596 
   1597     // Construct the new data.
   1598     size_t srcSegmentEnd;
   1599     unsigned srcSegmentLength;
   1600     srcSegmentStart = 0;
   1601     unsigned dstOffset = 0;
   1602 
   1603     if (is8Bit()) {
   1604         UChar* data;
   1605         RefPtr<StringImpl> newImpl = createUninitialized(newSize, data);
   1606 
   1607         while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) {
   1608             srcSegmentLength = srcSegmentEnd - srcSegmentStart;
   1609             for (unsigned i = 0; i < srcSegmentLength; ++i)
   1610                 data[i + dstOffset] = characters8()[i + srcSegmentStart];
   1611 
   1612             dstOffset += srcSegmentLength;
   1613             memcpy(data + dstOffset, replacement, repStrLength * sizeof(UChar));
   1614 
   1615             dstOffset += repStrLength;
   1616             srcSegmentStart = srcSegmentEnd + 1;
   1617         }
   1618 
   1619         srcSegmentLength = m_length - srcSegmentStart;
   1620         for (unsigned i = 0; i < srcSegmentLength; ++i)
   1621             data[i + dstOffset] = characters8()[i + srcSegmentStart];
   1622 
   1623         ASSERT(dstOffset + srcSegmentLength == newImpl->length());
   1624 
   1625         return newImpl.release();
   1626     }
   1627 
   1628     UChar* data;
   1629     RefPtr<StringImpl> newImpl = createUninitialized(newSize, data);
   1630 
   1631     while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) {
   1632         srcSegmentLength = srcSegmentEnd - srcSegmentStart;
   1633         memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar));
   1634 
   1635         dstOffset += srcSegmentLength;
   1636         memcpy(data + dstOffset, replacement, repStrLength * sizeof(UChar));
   1637 
   1638         dstOffset += repStrLength;
   1639         srcSegmentStart = srcSegmentEnd + 1;
   1640     }
   1641 
   1642     srcSegmentLength = m_length - srcSegmentStart;
   1643     memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar));
   1644 
   1645     ASSERT(dstOffset + srcSegmentLength == newImpl->length());
   1646 
   1647     return newImpl.release();
   1648 }
   1649 
   1650 PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* replacement)
   1651 {
   1652     if (!pattern || !replacement)
   1653         return this;
   1654 
   1655     unsigned patternLength = pattern->length();
   1656     if (!patternLength)
   1657         return this;
   1658 
   1659     unsigned repStrLength = replacement->length();
   1660     size_t srcSegmentStart = 0;
   1661     unsigned matchCount = 0;
   1662 
   1663     // Count the matches.
   1664     while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) {
   1665         ++matchCount;
   1666         srcSegmentStart += patternLength;
   1667     }
   1668 
   1669     // If we have 0 matches, we don't have to do any more work
   1670     if (!matchCount)
   1671         return this;
   1672 
   1673     unsigned newSize = m_length - matchCount * patternLength;
   1674     RELEASE_ASSERT(!repStrLength || matchCount <= numeric_limits<unsigned>::max() / repStrLength);
   1675 
   1676     RELEASE_ASSERT(newSize <= (numeric_limits<unsigned>::max() - matchCount * repStrLength));
   1677 
   1678     newSize += matchCount * repStrLength;
   1679 
   1680 
   1681     // Construct the new data
   1682     size_t srcSegmentEnd;
   1683     unsigned srcSegmentLength;
   1684     srcSegmentStart = 0;
   1685     unsigned dstOffset = 0;
   1686     bool srcIs8Bit = is8Bit();
   1687     bool replacementIs8Bit = replacement->is8Bit();
   1688 
   1689     // There are 4 cases:
   1690     // 1. This and replacement are both 8 bit.
   1691     // 2. This and replacement are both 16 bit.
   1692     // 3. This is 8 bit and replacement is 16 bit.
   1693     // 4. This is 16 bit and replacement is 8 bit.
   1694     if (srcIs8Bit && replacementIs8Bit) {
   1695         // Case 1
   1696         LChar* data;
   1697         RefPtr<StringImpl> newImpl = createUninitialized(newSize, data);
   1698         while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) {
   1699             srcSegmentLength = srcSegmentEnd - srcSegmentStart;
   1700             memcpy(data + dstOffset, characters8() + srcSegmentStart, srcSegmentLength * sizeof(LChar));
   1701             dstOffset += srcSegmentLength;
   1702             memcpy(data + dstOffset, replacement->characters8(), repStrLength * sizeof(LChar));
   1703             dstOffset += repStrLength;
   1704             srcSegmentStart = srcSegmentEnd + patternLength;
   1705         }
   1706 
   1707         srcSegmentLength = m_length - srcSegmentStart;
   1708         memcpy(data + dstOffset, characters8() + srcSegmentStart, srcSegmentLength * sizeof(LChar));
   1709 
   1710         ASSERT(dstOffset + srcSegmentLength == newImpl->length());
   1711 
   1712         return newImpl.release();
   1713     }
   1714 
   1715     UChar* data;
   1716     RefPtr<StringImpl> newImpl = createUninitialized(newSize, data);
   1717     while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) {
   1718         srcSegmentLength = srcSegmentEnd - srcSegmentStart;
   1719         if (srcIs8Bit) {
   1720             // Case 3.
   1721             for (unsigned i = 0; i < srcSegmentLength; ++i)
   1722                 data[i + dstOffset] = characters8()[i + srcSegmentStart];
   1723         } else {
   1724             // Case 2 & 4.
   1725             memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar));
   1726         }
   1727         dstOffset += srcSegmentLength;
   1728         if (replacementIs8Bit) {
   1729             // Cases 2 & 3.
   1730             for (unsigned i = 0; i < repStrLength; ++i)
   1731                 data[i + dstOffset] = replacement->characters8()[i];
   1732         } else {
   1733             // Case 4
   1734             memcpy(data + dstOffset, replacement->characters16(), repStrLength * sizeof(UChar));
   1735         }
   1736         dstOffset += repStrLength;
   1737         srcSegmentStart = srcSegmentEnd + patternLength;
   1738     }
   1739 
   1740     srcSegmentLength = m_length - srcSegmentStart;
   1741     if (srcIs8Bit) {
   1742         // Case 3.
   1743         for (unsigned i = 0; i < srcSegmentLength; ++i)
   1744             data[i + dstOffset] = characters8()[i + srcSegmentStart];
   1745     } else {
   1746         // Cases 2 & 4.
   1747         memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar));
   1748     }
   1749 
   1750     ASSERT(dstOffset + srcSegmentLength == newImpl->length());
   1751 
   1752     return newImpl.release();
   1753 }
   1754 
   1755 static inline bool stringImplContentEqual(const StringImpl* a, const StringImpl* b)
   1756 {
   1757     unsigned aLength = a->length();
   1758     unsigned bLength = b->length();
   1759     if (aLength != bLength)
   1760         return false;
   1761 
   1762     if (a->is8Bit()) {
   1763         if (b->is8Bit())
   1764             return equal(a->characters8(), b->characters8(), aLength);
   1765 
   1766         return equal(a->characters8(), b->characters16(), aLength);
   1767     }
   1768 
   1769     if (b->is8Bit())
   1770         return equal(a->characters16(), b->characters8(), aLength);
   1771 
   1772     return equal(a->characters16(), b->characters16(), aLength);
   1773 }
   1774 
   1775 bool equal(const StringImpl* a, const StringImpl* b)
   1776 {
   1777     if (a == b)
   1778         return true;
   1779     if (!a || !b)
   1780         return false;
   1781 
   1782     return stringImplContentEqual(a, b);
   1783 }
   1784 
   1785 template <typename CharType>
   1786 inline bool equalInternal(const StringImpl* a, const CharType* b, unsigned length)
   1787 {
   1788     if (!a)
   1789         return !b;
   1790     if (!b)
   1791         return false;
   1792 
   1793     if (a->length() != length)
   1794         return false;
   1795     if (a->is8Bit())
   1796         return equal(a->characters8(), b, length);
   1797     return equal(a->characters16(), b, length);
   1798 }
   1799 
   1800 bool equal(const StringImpl* a, const LChar* b, unsigned length)
   1801 {
   1802     return equalInternal(a, b, length);
   1803 }
   1804 
   1805 bool equal(const StringImpl* a, const UChar* b, unsigned length)
   1806 {
   1807     return equalInternal(a, b, length);
   1808 }
   1809 
   1810 bool equal(const StringImpl* a, const LChar* b)
   1811 {
   1812     if (!a)
   1813         return !b;
   1814     if (!b)
   1815         return !a;
   1816 
   1817     unsigned length = a->length();
   1818 
   1819     if (a->is8Bit()) {
   1820         const LChar* aPtr = a->characters8();
   1821         for (unsigned i = 0; i != length; ++i) {
   1822             LChar bc = b[i];
   1823             LChar ac = aPtr[i];
   1824             if (!bc)
   1825                 return false;
   1826             if (ac != bc)
   1827                 return false;
   1828         }
   1829 
   1830         return !b[length];
   1831     }
   1832 
   1833     const UChar* aPtr = a->characters16();
   1834     for (unsigned i = 0; i != length; ++i) {
   1835         LChar bc = b[i];
   1836         if (!bc)
   1837             return false;
   1838         if (aPtr[i] != bc)
   1839             return false;
   1840     }
   1841 
   1842     return !b[length];
   1843 }
   1844 
   1845 bool equalNonNull(const StringImpl* a, const StringImpl* b)
   1846 {
   1847     ASSERT(a && b);
   1848     if (a == b)
   1849         return true;
   1850 
   1851     return stringImplContentEqual(a, b);
   1852 }
   1853 
   1854 bool equalIgnoringCase(const StringImpl* a, const StringImpl* b)
   1855 {
   1856     if (a == b)
   1857         return true;
   1858     if (!a || !b)
   1859         return false;
   1860 
   1861     return CaseFoldingHash::equal(a, b);
   1862 }
   1863 
   1864 bool equalIgnoringCase(const StringImpl* a, const LChar* b)
   1865 {
   1866     if (!a)
   1867         return !b;
   1868     if (!b)
   1869         return !a;
   1870 
   1871     unsigned length = a->length();
   1872 
   1873     // Do a faster loop for the case where all the characters are ASCII.
   1874     UChar ored = 0;
   1875     bool equal = true;
   1876     if (a->is8Bit()) {
   1877         const LChar* as = a->characters8();
   1878         for (unsigned i = 0; i != length; ++i) {
   1879             LChar bc = b[i];
   1880             if (!bc)
   1881                 return false;
   1882             UChar ac = as[i];
   1883             ored |= ac;
   1884             equal = equal && (toASCIILower(ac) == toASCIILower(bc));
   1885         }
   1886 
   1887         // Do a slower implementation for cases that include non-ASCII characters.
   1888         if (ored & ~0x7F) {
   1889             equal = true;
   1890             for (unsigned i = 0; i != length; ++i)
   1891                 equal = equal && (foldCase(as[i]) == foldCase(b[i]));
   1892         }
   1893 
   1894         return equal && !b[length];
   1895     }
   1896 
   1897     const UChar* as = a->characters16();
   1898     for (unsigned i = 0; i != length; ++i) {
   1899         LChar bc = b[i];
   1900         if (!bc)
   1901             return false;
   1902         UChar ac = as[i];
   1903         ored |= ac;
   1904         equal = equal && (toASCIILower(ac) == toASCIILower(bc));
   1905     }
   1906 
   1907     // Do a slower implementation for cases that include non-ASCII characters.
   1908     if (ored & ~0x7F) {
   1909         equal = true;
   1910         for (unsigned i = 0; i != length; ++i) {
   1911             equal = equal && (foldCase(as[i]) == foldCase(b[i]));
   1912         }
   1913     }
   1914 
   1915     return equal && !b[length];
   1916 }
   1917 
   1918 bool equalIgnoringCaseNonNull(const StringImpl* a, const StringImpl* b)
   1919 {
   1920     ASSERT(a && b);
   1921     if (a == b)
   1922         return true;
   1923 
   1924     unsigned length = a->length();
   1925     if (length != b->length())
   1926         return false;
   1927 
   1928     if (a->is8Bit()) {
   1929         if (b->is8Bit())
   1930             return equalIgnoringCase(a->characters8(), b->characters8(), length);
   1931 
   1932         return equalIgnoringCase(b->characters16(), a->characters8(), length);
   1933     }
   1934 
   1935     if (b->is8Bit())
   1936         return equalIgnoringCase(a->characters16(), b->characters8(), length);
   1937 
   1938     return equalIgnoringCase(a->characters16(), b->characters16(), length);
   1939 }
   1940 
   1941 bool equalIgnoringNullity(StringImpl* a, StringImpl* b)
   1942 {
   1943     if (!a && b && !b->length())
   1944         return true;
   1945     if (!b && a && !a->length())
   1946         return true;
   1947     return equal(a, b);
   1948 }
   1949 
   1950 WTF::Unicode::Direction StringImpl::defaultWritingDirection(bool* hasStrongDirectionality)
   1951 {
   1952     for (unsigned i = 0; i < m_length; ++i) {
   1953         WTF::Unicode::Direction charDirection = WTF::Unicode::direction(is8Bit() ? characters8()[i] : characters16()[i]);
   1954         if (charDirection == WTF::Unicode::LeftToRight) {
   1955             if (hasStrongDirectionality)
   1956                 *hasStrongDirectionality = true;
   1957             return WTF::Unicode::LeftToRight;
   1958         }
   1959         if (charDirection == WTF::Unicode::RightToLeft || charDirection == WTF::Unicode::RightToLeftArabic) {
   1960             if (hasStrongDirectionality)
   1961                 *hasStrongDirectionality = true;
   1962             return WTF::Unicode::RightToLeft;
   1963         }
   1964     }
   1965     if (hasStrongDirectionality)
   1966         *hasStrongDirectionality = false;
   1967     return WTF::Unicode::LeftToRight;
   1968 }
   1969 
   1970 size_t StringImpl::sizeInBytes() const
   1971 {
   1972     size_t size = length();
   1973     if (!is8Bit())
   1974         size *= 2;
   1975     return size + sizeof(*this);
   1976 }
   1977 
   1978 } // namespace WTF
   1979