| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Dirk Mueller ( mueller@kde.org ) | 4 * (C) 2001 Dirk Mueller ( mueller@kde.org ) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All r
ights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All r
ights reserved. |
| 6 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) | 6 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 int32_t realLength = Unicode::toUpper(data16, length, source16, m_length, &e
rror); | 644 int32_t realLength = Unicode::toUpper(data16, length, source16, m_length, &e
rror); |
| 645 if (!error && realLength == length) | 645 if (!error && realLength == length) |
| 646 return newImpl; | 646 return newImpl; |
| 647 newImpl = createUninitialized(realLength, data16); | 647 newImpl = createUninitialized(realLength, data16); |
| 648 Unicode::toUpper(data16, realLength, source16, m_length, &error); | 648 Unicode::toUpper(data16, realLength, source16, m_length, &error); |
| 649 if (error) | 649 if (error) |
| 650 return this; | 650 return this; |
| 651 return newImpl.release(); | 651 return newImpl.release(); |
| 652 } | 652 } |
| 653 | 653 |
| 654 static bool inline localeIdMatchesLang(const AtomicString& localeId, const char*
lang) | 654 ALWAYS_INLINE static bool startsWithIgnoringCase(const StringImpl* stringImpl, c
onst LChar* prefix, unsigned prefixLength) |
| 655 { | 655 { |
| 656 if (equalIgnoringCase(localeId, lang)) | 656 ASSERT(stringImpl); |
| 657 return true; | 657 if (prefixLength > stringImpl->length()) |
| 658 static char localeIdPrefix[4]; | 658 return false; |
| 659 static const char delimeter[4] = "-_@"; | 659 if (stringImpl->is8Bit()) |
| 660 return equalIgnoringCase(stringImpl->characters8(), prefix, prefixLength
); |
| 661 return equalIgnoringCase(stringImpl->characters16(), prefix, prefixLength); |
| 662 } |
| 660 | 663 |
| 664 static inline bool localeIdMatchesLang(const AtomicString& localeId, const char*
lang) |
| 665 { |
| 661 size_t langLength = strlen(lang); | 666 size_t langLength = strlen(lang); |
| 662 RELEASE_ASSERT(langLength >= 2 && langLength <= 3); | 667 RELEASE_ASSERT(langLength >= 2 && langLength <= 3); |
| 663 strncpy(localeIdPrefix, lang, langLength); | 668 if (!localeId.impl() || !startsWithIgnoringCase(localeId.impl(), reinterpret
_cast<const LChar*>(lang), langLength)) |
| 664 for (int i = 0; i < 3; ++i) { | 669 return false; |
| 665 localeIdPrefix[langLength] = delimeter[i]; | 670 if (localeId.impl()->length() == langLength) |
| 666 // case-insensitive comparison | 671 return true; |
| 667 if (localeId.impl() && localeId.impl()->startsWith(localeIdPrefix, langL
ength + 1, TextCaseInsensitive)) | 672 const UChar maybeDelimiter = (*localeId.impl())[langLength]; |
| 668 return true; | 673 return maybeDelimiter == '-' || maybeDelimiter == '_' || maybeDelimiter == '
@'; |
| 669 } | |
| 670 return false; | |
| 671 } | 674 } |
| 672 | 675 |
| 673 typedef int32_t (*icuCaseConverter)(UChar*, int32_t, const UChar*, int32_t, cons
t char*, UErrorCode*); | 676 typedef int32_t (*icuCaseConverter)(UChar*, int32_t, const UChar*, int32_t, cons
t char*, UErrorCode*); |
| 674 | 677 |
| 675 static PassRefPtr<StringImpl> caseConvert(const UChar* source16, size_t length,
icuCaseConverter converter, const char* locale, StringImpl* originalString) | 678 static PassRefPtr<StringImpl> caseConvert(const UChar* source16, size_t length,
icuCaseConverter converter, const char* locale, StringImpl* originalString) |
| 676 { | 679 { |
| 677 UChar* data16; | 680 UChar* data16; |
| 678 size_t targetLength = length; | 681 size_t targetLength = length; |
| 679 RefPtr<StringImpl> output = StringImpl::createUninitialized(length, data16); | 682 RefPtr<StringImpl> output = StringImpl::createUninitialized(length, data16); |
| 680 do { | 683 do { |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 return reverseFindIgnoringCaseInner(characters8(), matchString->char
acters8(), index, ourLength, matchLength); | 1459 return reverseFindIgnoringCaseInner(characters8(), matchString->char
acters8(), index, ourLength, matchLength); |
| 1457 return reverseFindIgnoringCaseInner(characters8(), matchString->characte
rs16(), index, ourLength, matchLength); | 1460 return reverseFindIgnoringCaseInner(characters8(), matchString->characte
rs16(), index, ourLength, matchLength); |
| 1458 } | 1461 } |
| 1459 | 1462 |
| 1460 if (matchString->is8Bit()) | 1463 if (matchString->is8Bit()) |
| 1461 return reverseFindIgnoringCaseInner(characters16(), matchString->charact
ers8(), index, ourLength, matchLength); | 1464 return reverseFindIgnoringCaseInner(characters16(), matchString->charact
ers8(), index, ourLength, matchLength); |
| 1462 | 1465 |
| 1463 return reverseFindIgnoringCaseInner(characters16(), matchString->characters1
6(), index, ourLength, matchLength); | 1466 return reverseFindIgnoringCaseInner(characters16(), matchString->characters1
6(), index, ourLength, matchLength); |
| 1464 } | 1467 } |
| 1465 | 1468 |
| 1466 ALWAYS_INLINE static bool equalInner(const StringImpl* stringImpl, unsigned star
tOffset, const char* matchString, unsigned matchLength, TextCaseSensitivity case
Sensitivity) | 1469 ALWAYS_INLINE static bool equalInner(const StringImpl* stringImpl, unsigned star
tOffset, const LChar* matchString, unsigned matchLength) |
| 1467 { | 1470 { |
| 1468 ASSERT(stringImpl); | 1471 ASSERT(stringImpl); |
| 1469 ASSERT(matchLength <= stringImpl->length()); | 1472 ASSERT(matchLength <= stringImpl->length()); |
| 1470 ASSERT(startOffset + matchLength <= stringImpl->length()); | 1473 ASSERT(startOffset + matchLength <= stringImpl->length()); |
| 1471 | 1474 |
| 1472 if (caseSensitivity == TextCaseSensitive) { | |
| 1473 if (stringImpl->is8Bit()) | |
| 1474 return equal(stringImpl->characters8() + startOffset, reinterpret_ca
st<const LChar*>(matchString), matchLength); | |
| 1475 return equal(stringImpl->characters16() + startOffset, reinterpret_cast<
const LChar*>(matchString), matchLength); | |
| 1476 } | |
| 1477 if (stringImpl->is8Bit()) | 1475 if (stringImpl->is8Bit()) |
| 1478 return equalIgnoringCase(stringImpl->characters8() + startOffset, reinte
rpret_cast<const LChar*>(matchString), matchLength); | 1476 return equal(stringImpl->characters8() + startOffset, matchString, match
Length); |
| 1479 return equalIgnoringCase(stringImpl->characters16() + startOffset, reinterpr
et_cast<const LChar*>(matchString), matchLength); | 1477 return equal(stringImpl->characters16() + startOffset, matchString, matchLen
gth); |
| 1480 } | 1478 } |
| 1481 | 1479 |
| 1482 bool StringImpl::startsWith(UChar character) const | 1480 bool StringImpl::startsWith(UChar character) const |
| 1483 { | 1481 { |
| 1484 return m_length && (*this)[0] == character; | 1482 return m_length && (*this)[0] == character; |
| 1485 } | 1483 } |
| 1486 | 1484 |
| 1487 bool StringImpl::startsWith(const char* matchString, unsigned matchLength, TextC
aseSensitivity caseSensitivity) const | 1485 bool StringImpl::startsWith(const char* matchString, unsigned matchLength) const |
| 1488 { | 1486 { |
| 1489 ASSERT(matchLength); | 1487 ASSERT(matchLength); |
| 1490 if (matchLength > length()) | 1488 if (matchLength > length()) |
| 1491 return false; | 1489 return false; |
| 1492 return equalInner(this, 0, matchString, matchLength, caseSensitivity); | 1490 return equalInner(this, 0, reinterpret_cast<const LChar*>(matchString), matc
hLength); |
| 1493 } | 1491 } |
| 1494 | 1492 |
| 1495 bool StringImpl::endsWith(StringImpl* matchString, TextCaseSensitivity caseSensi
tivity) | 1493 bool StringImpl::endsWith(StringImpl* matchString, TextCaseSensitivity caseSensi
tivity) |
| 1496 { | 1494 { |
| 1497 ASSERT(matchString); | 1495 ASSERT(matchString); |
| 1498 if (m_length >= matchString->m_length) { | 1496 if (m_length >= matchString->m_length) { |
| 1499 unsigned start = m_length - matchString->m_length; | 1497 unsigned start = m_length - matchString->m_length; |
| 1500 if (caseSensitivity == TextCaseSensitive) | 1498 if (caseSensitivity == TextCaseSensitive) |
| 1501 return find(matchString, start) == start; | 1499 return find(matchString, start) == start; |
| 1502 return findIgnoringCase(matchString, start) == start; | 1500 return findIgnoringCase(matchString, start) == start; |
| 1503 } | 1501 } |
| 1504 return false; | 1502 return false; |
| 1505 } | 1503 } |
| 1506 | 1504 |
| 1507 bool StringImpl::endsWith(UChar character) const | 1505 bool StringImpl::endsWith(UChar character) const |
| 1508 { | 1506 { |
| 1509 return m_length && (*this)[m_length - 1] == character; | 1507 return m_length && (*this)[m_length - 1] == character; |
| 1510 } | 1508 } |
| 1511 | 1509 |
| 1512 bool StringImpl::endsWith(const char* matchString, unsigned matchLength, TextCas
eSensitivity caseSensitivity) const | 1510 bool StringImpl::endsWith(const char* matchString, unsigned matchLength) const |
| 1513 { | 1511 { |
| 1514 ASSERT(matchLength); | 1512 ASSERT(matchLength); |
| 1515 if (matchLength > length()) | 1513 if (matchLength > length()) |
| 1516 return false; | 1514 return false; |
| 1517 unsigned startOffset = length() - matchLength; | 1515 return equalInner(this, length() - matchLength, reinterpret_cast<const LChar
*>(matchString), matchLength); |
| 1518 return equalInner(this, startOffset, matchString, matchLength, caseSensitivi
ty); | |
| 1519 } | 1516 } |
| 1520 | 1517 |
| 1521 PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC) | 1518 PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC) |
| 1522 { | 1519 { |
| 1523 if (oldC == newC) | 1520 if (oldC == newC) |
| 1524 return this; | 1521 return this; |
| 1525 | 1522 |
| 1526 if (find(oldC) == kNotFound) | 1523 if (find(oldC) == kNotFound) |
| 1527 return this; | 1524 return this; |
| 1528 | 1525 |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2109 } else if (localeIdMatchesLang(localeIdentifier, "lt")) { | 2106 } else if (localeIdMatchesLang(localeIdentifier, "lt")) { |
| 2110 // TODO(rob.buis) implement upper-casing rules for lt | 2107 // TODO(rob.buis) implement upper-casing rules for lt |
| 2111 // like in StringImpl::upper(locale). | 2108 // like in StringImpl::upper(locale). |
| 2112 } | 2109 } |
| 2113 } | 2110 } |
| 2114 | 2111 |
| 2115 return toUpper(c); | 2112 return toUpper(c); |
| 2116 } | 2113 } |
| 2117 | 2114 |
| 2118 } // namespace WTF | 2115 } // namespace WTF |
| OLD | NEW |