| 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 ALWAYS_INLINE static bool startsWithIgnoringCase(const StringImpl* stringImpl, c
onst LChar* prefix, unsigned prefixLength) | |
| 655 { | |
| 656 ASSERT(stringImpl); | |
| 657 if (prefixLength > stringImpl->length()) | |
| 658 return false; | |
| 659 if (stringImpl->is8Bit()) | |
| 660 return equalIgnoringCase(stringImpl->characters8(), prefix, prefixLength
); | |
| 661 return equalIgnoringCase(stringImpl->characters16(), prefix, prefixLength); | |
| 662 } | |
| 663 | |
| 664 static inline bool localeIdMatchesLang(const AtomicString& localeId, const char*
lang) | 654 static inline bool localeIdMatchesLang(const AtomicString& localeId, const char*
lang) |
| 665 { | 655 { |
| 666 size_t langLength = strlen(lang); | 656 size_t langLength = strlen(lang); |
| 667 RELEASE_ASSERT(langLength >= 2 && langLength <= 3); | 657 RELEASE_ASSERT(langLength >= 2 && langLength <= 3); |
| 668 if (!localeId.impl() || !startsWithIgnoringCase(localeId.impl(), reinterpret
_cast<const LChar*>(lang), langLength)) | 658 if (!localeId.impl() || !localeId.impl()->startsWithIgnoringCase(lang, langL
ength)) |
| 669 return false; | 659 return false; |
| 670 if (localeId.impl()->length() == langLength) | 660 if (localeId.impl()->length() == langLength) |
| 671 return true; | 661 return true; |
| 672 const UChar maybeDelimiter = (*localeId.impl())[langLength]; | 662 const UChar maybeDelimiter = (*localeId.impl())[langLength]; |
| 673 return maybeDelimiter == '-' || maybeDelimiter == '_' || maybeDelimiter == '
@'; | 663 return maybeDelimiter == '-' || maybeDelimiter == '_' || maybeDelimiter == '
@'; |
| 674 } | 664 } |
| 675 | 665 |
| 676 typedef int32_t (*icuCaseConverter)(UChar*, int32_t, const UChar*, int32_t, cons
t char*, UErrorCode*); | 666 typedef int32_t (*icuCaseConverter)(UChar*, int32_t, const UChar*, int32_t, cons
t char*, UErrorCode*); |
| 677 | 667 |
| 678 static PassRefPtr<StringImpl> caseConvert(const UChar* source16, size_t length,
icuCaseConverter converter, const char* locale, StringImpl* originalString) | 668 static PassRefPtr<StringImpl> caseConvert(const UChar* source16, size_t length,
icuCaseConverter converter, const char* locale, StringImpl* originalString) |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 return reverseFindInner(characters8(), matchString->characters8(), i
ndex, ourLength, matchLength); | 1453 return reverseFindInner(characters8(), matchString->characters8(), i
ndex, ourLength, matchLength); |
| 1464 return reverseFindInner(characters8(), matchString->characters16(), inde
x, ourLength, matchLength); | 1454 return reverseFindInner(characters8(), matchString->characters16(), inde
x, ourLength, matchLength); |
| 1465 } | 1455 } |
| 1466 | 1456 |
| 1467 if (matchString->is8Bit()) | 1457 if (matchString->is8Bit()) |
| 1468 return reverseFindInner(characters16(), matchString->characters8(), inde
x, ourLength, matchLength); | 1458 return reverseFindInner(characters16(), matchString->characters8(), inde
x, ourLength, matchLength); |
| 1469 | 1459 |
| 1470 return reverseFindInner(characters16(), matchString->characters16(), index,
ourLength, matchLength); | 1460 return reverseFindInner(characters16(), matchString->characters16(), index,
ourLength, matchLength); |
| 1471 } | 1461 } |
| 1472 | 1462 |
| 1473 ALWAYS_INLINE static bool equalInner(const StringImpl* stringImpl, unsigned star
tOffset, const LChar* matchString, unsigned matchLength) | 1463 ALWAYS_INLINE static bool equalSubstring(const StringImpl* stringImpl, unsigned
startOffset, const LChar* matchString, unsigned matchLength) |
| 1474 { | 1464 { |
| 1475 ASSERT(stringImpl); | 1465 ASSERT(stringImpl); |
| 1476 ASSERT(matchLength <= stringImpl->length()); | 1466 ASSERT(matchLength <= stringImpl->length()); |
| 1477 ASSERT(startOffset + matchLength <= stringImpl->length()); | 1467 ASSERT(startOffset + matchLength <= stringImpl->length()); |
| 1478 | 1468 |
| 1479 if (stringImpl->is8Bit()) | 1469 if (stringImpl->is8Bit()) |
| 1480 return equal(stringImpl->characters8() + startOffset, matchString, match
Length); | 1470 return equal(stringImpl->characters8() + startOffset, matchString, match
Length); |
| 1481 return equal(stringImpl->characters16() + startOffset, matchString, matchLen
gth); | 1471 return equal(stringImpl->characters16() + startOffset, matchString, matchLen
gth); |
| 1482 } | 1472 } |
| 1483 | 1473 |
| 1484 bool StringImpl::startsWith(UChar character) const | 1474 bool StringImpl::startsWith(UChar character) const |
| 1485 { | 1475 { |
| 1486 return m_length && (*this)[0] == character; | 1476 return m_length && (*this)[0] == character; |
| 1487 } | 1477 } |
| 1488 | 1478 |
| 1489 bool StringImpl::startsWith(const char* matchString, unsigned matchLength) const | 1479 bool StringImpl::startsWith(const char* prefixString, unsigned prefixLength) con
st |
| 1490 { | 1480 { |
| 1491 ASSERT(matchLength); | 1481 ASSERT(prefixLength); |
| 1492 if (matchLength > length()) | 1482 if (prefixLength > length()) |
| 1493 return false; | 1483 return false; |
| 1494 return equalInner(this, 0, reinterpret_cast<const LChar*>(matchString), matc
hLength); | 1484 return equalSubstring(this, 0, reinterpret_cast<const LChar*>(prefixString),
prefixLength); |
| 1495 } | 1485 } |
| 1496 | 1486 |
| 1497 ALWAYS_INLINE static bool equalSubstring(const StringImpl* stringImpl, unsigned
startOffset, const StringImpl* matchString) | 1487 ALWAYS_INLINE static bool equalSubstring(const StringImpl* stringImpl, unsigned
startOffset, const StringImpl* matchString) |
| 1498 { | 1488 { |
| 1499 ASSERT(stringImpl); | 1489 ASSERT(stringImpl); |
| 1500 ASSERT(matchString); | 1490 ASSERT(matchString); |
| 1501 ASSERT(matchString->length() <= stringImpl->length()); | 1491 ASSERT(matchString->length() <= stringImpl->length()); |
| 1502 ASSERT(startOffset + matchString->length() <= stringImpl->length()); | 1492 ASSERT(startOffset + matchString->length() <= stringImpl->length()); |
| 1503 | 1493 |
| 1504 unsigned matchLength = matchString->length(); | 1494 unsigned matchLength = matchString->length(); |
| 1505 if (stringImpl->is8Bit()) { | |
| 1506 const LChar* start = stringImpl->characters8() + startOffset; | |
| 1507 if (matchString->is8Bit()) | |
| 1508 return equal(start, matchString->characters8(), matchLength); | |
| 1509 return equal(start, matchString->characters16(), matchLength); | |
| 1510 } | |
| 1511 const UChar* start = stringImpl->characters16() + startOffset; | |
| 1512 if (matchString->is8Bit()) | 1495 if (matchString->is8Bit()) |
| 1513 return equal(start, matchString->characters8(), matchLength); | 1496 return equalSubstring(stringImpl, startOffset, matchString->characters8(
), matchLength); |
| 1514 return equal(start, matchString->characters16(), matchLength); | 1497 if (stringImpl->is8Bit()) |
| 1498 return equal(stringImpl->characters8() + startOffset, matchString->chara
cters16(), matchLength); |
| 1499 return equal(stringImpl->characters16() + startOffset, matchString->characte
rs16(), matchLength); |
| 1515 } | 1500 } |
| 1516 | 1501 |
| 1517 bool StringImpl::startsWith(const StringImpl* prefix) const | 1502 bool StringImpl::startsWith(const StringImpl* prefix) const |
| 1518 { | 1503 { |
| 1519 ASSERT(prefix); | 1504 ASSERT(prefix); |
| 1520 if (prefix->length() > length()) | 1505 if (prefix->length() > length()) |
| 1521 return false; | 1506 return false; |
| 1522 return equalSubstring(this, 0, prefix); | 1507 return equalSubstring(this, 0, prefix); |
| 1523 } | 1508 } |
| 1524 | 1509 |
| 1510 ALWAYS_INLINE static bool equalSubstringIgnoringCase(const StringImpl* stringImp
l, unsigned startOffset, const LChar* matchString, unsigned matchLength) |
| 1511 { |
| 1512 ASSERT(stringImpl); |
| 1513 ASSERT(matchLength <= stringImpl->length()); |
| 1514 ASSERT(startOffset + matchLength <= stringImpl->length()); |
| 1515 |
| 1516 if (stringImpl->is8Bit()) |
| 1517 return equalIgnoringCase(stringImpl->characters8() + startOffset, matchS
tring, matchLength); |
| 1518 return equalIgnoringCase(stringImpl->characters16() + startOffset, matchStri
ng, matchLength); |
| 1519 } |
| 1520 |
| 1521 bool StringImpl::startsWithIgnoringCase(const char* prefixString, unsigned prefi
xLength) const |
| 1522 { |
| 1523 ASSERT(prefixLength); |
| 1524 if (prefixLength > length()) |
| 1525 return false; |
| 1526 return equalSubstringIgnoringCase(this, 0, reinterpret_cast<const LChar*>(pr
efixString), prefixLength); |
| 1527 } |
| 1528 |
| 1525 ALWAYS_INLINE static bool equalSubstringIgnoringCase(const StringImpl* stringImp
l, unsigned startOffset, const StringImpl* matchString) | 1529 ALWAYS_INLINE static bool equalSubstringIgnoringCase(const StringImpl* stringImp
l, unsigned startOffset, const StringImpl* matchString) |
| 1526 { | 1530 { |
| 1527 ASSERT(stringImpl); | 1531 ASSERT(stringImpl); |
| 1528 ASSERT(matchString); | 1532 ASSERT(matchString); |
| 1529 ASSERT(matchString->length() <= stringImpl->length()); | 1533 ASSERT(matchString->length() <= stringImpl->length()); |
| 1530 ASSERT(startOffset + matchString->length() <= stringImpl->length()); | 1534 ASSERT(startOffset + matchString->length() <= stringImpl->length()); |
| 1531 | 1535 |
| 1532 unsigned matchLength = matchString->length(); | 1536 unsigned matchLength = matchString->length(); |
| 1533 if (stringImpl->is8Bit()) { | |
| 1534 const LChar* start = stringImpl->characters8() + startOffset; | |
| 1535 if (matchString->is8Bit()) | |
| 1536 return equalIgnoringCase(start, matchString->characters8(), matchLen
gth); | |
| 1537 return equalIgnoringCase(start, matchString->characters16(), matchLength
); | |
| 1538 } | |
| 1539 const UChar* start = stringImpl->characters16() + startOffset; | |
| 1540 if (matchString->is8Bit()) | 1537 if (matchString->is8Bit()) |
| 1541 return equalIgnoringCase(start, matchString->characters8(), matchLength)
; | 1538 return equalSubstringIgnoringCase(stringImpl, startOffset, matchString->
characters8(), matchLength); |
| 1542 return equalIgnoringCase(start, matchString->characters16(), matchLength); | 1539 if (stringImpl->is8Bit()) |
| 1540 return equalIgnoringCase(stringImpl->characters8() + startOffset, matchS
tring->characters16(), matchLength); |
| 1541 return equalIgnoringCase(stringImpl->characters16() + startOffset, matchStri
ng->characters16(), matchLength); |
| 1543 } | 1542 } |
| 1544 | 1543 |
| 1545 bool StringImpl::startsWithIgnoringCase(const StringImpl* prefix) const | 1544 bool StringImpl::startsWithIgnoringCase(const StringImpl* prefix) const |
| 1546 { | 1545 { |
| 1547 ASSERT(prefix); | 1546 ASSERT(prefix); |
| 1548 if (prefix->length() > length()) | 1547 if (prefix->length() > length()) |
| 1549 return false; | 1548 return false; |
| 1550 return equalSubstringIgnoringCase(this, 0, prefix); | 1549 return equalSubstringIgnoringCase(this, 0, prefix); |
| 1551 } | 1550 } |
| 1552 | 1551 |
| 1552 ALWAYS_INLINE static bool equalSubstringIgnoringASCIICase(const StringImpl* stri
ngImpl, unsigned startOffset, const LChar* matchString, unsigned matchLength) |
| 1553 { |
| 1554 ASSERT(stringImpl); |
| 1555 ASSERT(matchLength <= stringImpl->length()); |
| 1556 ASSERT(startOffset + matchLength <= stringImpl->length()); |
| 1557 |
| 1558 if (stringImpl->is8Bit()) |
| 1559 return equalIgnoringASCIICase(stringImpl->characters8() + startOffset, m
atchString, matchLength); |
| 1560 return equalIgnoringASCIICase(stringImpl->characters16() + startOffset, matc
hString, matchLength); |
| 1561 } |
| 1562 |
| 1563 bool StringImpl::startsWithIgnoringASCIICase(const char* prefixString, unsigned
prefixLength) const |
| 1564 { |
| 1565 ASSERT(prefixLength); |
| 1566 if (prefixLength > length()) |
| 1567 return false; |
| 1568 return equalSubstringIgnoringASCIICase(this, 0, reinterpret_cast<const LChar
*>(prefixString), prefixLength); |
| 1569 } |
| 1570 |
| 1553 ALWAYS_INLINE static bool equalSubstringIgnoringASCIICase(const StringImpl* stri
ngImpl, unsigned startOffset, const StringImpl* matchString) | 1571 ALWAYS_INLINE static bool equalSubstringIgnoringASCIICase(const StringImpl* stri
ngImpl, unsigned startOffset, const StringImpl* matchString) |
| 1554 { | 1572 { |
| 1555 ASSERT(stringImpl); | 1573 ASSERT(stringImpl); |
| 1556 ASSERT(matchString); | 1574 ASSERT(matchString); |
| 1557 ASSERT(matchString->length() <= stringImpl->length()); | 1575 ASSERT(matchString->length() <= stringImpl->length()); |
| 1558 ASSERT(startOffset + matchString->length() <= stringImpl->length()); | 1576 ASSERT(startOffset + matchString->length() <= stringImpl->length()); |
| 1559 | 1577 |
| 1560 unsigned matchLength = matchString->length(); | 1578 unsigned matchLength = matchString->length(); |
| 1561 if (stringImpl->is8Bit()) { | |
| 1562 const LChar* start = stringImpl->characters8() + startOffset; | |
| 1563 if (matchString->is8Bit()) | |
| 1564 return equalIgnoringASCIICase(start, matchString->characters8(), mat
chLength); | |
| 1565 return equalIgnoringASCIICase(start, matchString->characters16(), matchL
ength); | |
| 1566 } | |
| 1567 const UChar* start = stringImpl->characters16() + startOffset; | |
| 1568 if (matchString->is8Bit()) | 1579 if (matchString->is8Bit()) |
| 1569 return equalIgnoringASCIICase(start, matchString->characters8(), matchLe
ngth); | 1580 return equalSubstringIgnoringASCIICase(stringImpl, startOffset, matchStr
ing->characters8(), matchLength); |
| 1570 return equalIgnoringASCIICase(start, matchString->characters16(), matchLengt
h); | 1581 if (stringImpl->is8Bit()) |
| 1582 return equalIgnoringASCIICase(stringImpl->characters8() + startOffset, m
atchString->characters16(), matchLength); |
| 1583 return equalIgnoringASCIICase(stringImpl->characters16() + startOffset, matc
hString->characters16(), matchLength); |
| 1571 } | 1584 } |
| 1572 | 1585 |
| 1573 bool StringImpl::startsWithIgnoringASCIICase(const StringImpl* prefix) const | 1586 bool StringImpl::startsWithIgnoringASCIICase(const StringImpl* prefix) const |
| 1574 { | 1587 { |
| 1575 ASSERT(prefix); | 1588 ASSERT(prefix); |
| 1576 if (prefix->length() > length()) | 1589 if (prefix->length() > length()) |
| 1577 return false; | 1590 return false; |
| 1578 return equalSubstringIgnoringASCIICase(this, 0, prefix); | 1591 return equalSubstringIgnoringASCIICase(this, 0, prefix); |
| 1579 } | 1592 } |
| 1580 | 1593 |
| 1581 bool StringImpl::endsWith(UChar character) const | 1594 bool StringImpl::endsWith(UChar character) const |
| 1582 { | 1595 { |
| 1583 return m_length && (*this)[m_length - 1] == character; | 1596 return m_length && (*this)[m_length - 1] == character; |
| 1584 } | 1597 } |
| 1585 | 1598 |
| 1586 bool StringImpl::endsWith(const char* matchString, unsigned matchLength) const | 1599 bool StringImpl::endsWith(const char* suffixString, unsigned suffixLength) const |
| 1587 { | 1600 { |
| 1588 ASSERT(matchLength); | 1601 ASSERT(suffixLength); |
| 1589 if (matchLength > length()) | 1602 if (suffixLength > length()) |
| 1590 return false; | 1603 return false; |
| 1591 return equalInner(this, length() - matchLength, reinterpret_cast<const LChar
*>(matchString), matchLength); | 1604 return equalSubstring(this, length() - suffixLength, reinterpret_cast<const
LChar*>(suffixString), suffixLength); |
| 1592 } | 1605 } |
| 1593 | 1606 |
| 1594 bool StringImpl::endsWith(const StringImpl* suffix) const | 1607 bool StringImpl::endsWith(const StringImpl* suffix) const |
| 1595 { | 1608 { |
| 1596 ASSERT(suffix); | 1609 ASSERT(suffix); |
| 1597 unsigned suffixLength = suffix->length(); | 1610 unsigned suffixLength = suffix->length(); |
| 1598 if (suffixLength > length()) | 1611 if (suffixLength > length()) |
| 1599 return false; | 1612 return false; |
| 1600 return equalSubstring(this, length() - suffixLength, suffix); | 1613 return equalSubstring(this, length() - suffixLength, suffix); |
| 1601 } | 1614 } |
| 1602 | 1615 |
| 1616 bool StringImpl::endsWithIgnoringCase(const char* suffixString, unsigned suffixL
ength) const |
| 1617 { |
| 1618 ASSERT(suffixLength); |
| 1619 if (suffixLength > length()) |
| 1620 return false; |
| 1621 return equalSubstringIgnoringCase(this, length() - suffixLength, reinterpret
_cast<const LChar*>(suffixString), suffixLength); |
| 1622 } |
| 1623 |
| 1603 bool StringImpl::endsWithIgnoringCase(const StringImpl* suffix) const | 1624 bool StringImpl::endsWithIgnoringCase(const StringImpl* suffix) const |
| 1604 { | 1625 { |
| 1605 ASSERT(suffix); | 1626 ASSERT(suffix); |
| 1606 unsigned suffixLength = suffix->length(); | 1627 unsigned suffixLength = suffix->length(); |
| 1607 if (suffixLength > length()) | 1628 if (suffixLength > length()) |
| 1608 return false; | 1629 return false; |
| 1609 return equalSubstringIgnoringCase(this, length() - suffixLength, suffix); | 1630 return equalSubstringIgnoringCase(this, length() - suffixLength, suffix); |
| 1610 } | 1631 } |
| 1611 | 1632 |
| 1633 bool StringImpl::endsWithIgnoringASCIICase(const char* suffixString, unsigned su
ffixLength) const |
| 1634 { |
| 1635 ASSERT(suffixLength); |
| 1636 if (suffixLength > length()) |
| 1637 return false; |
| 1638 return equalSubstringIgnoringASCIICase(this, length() - suffixLength, reinte
rpret_cast<const LChar*>(suffixString), suffixLength); |
| 1639 } |
| 1640 |
| 1612 bool StringImpl::endsWithIgnoringASCIICase(const StringImpl* suffix) const | 1641 bool StringImpl::endsWithIgnoringASCIICase(const StringImpl* suffix) const |
| 1613 { | 1642 { |
| 1614 ASSERT(suffix); | 1643 ASSERT(suffix); |
| 1615 unsigned suffixLength = suffix->length(); | 1644 unsigned suffixLength = suffix->length(); |
| 1616 if (suffixLength > length()) | 1645 if (suffixLength > length()) |
| 1617 return false; | 1646 return false; |
| 1618 return equalSubstringIgnoringASCIICase(this, length() - suffixLength, suffix
); | 1647 return equalSubstringIgnoringASCIICase(this, length() - suffixLength, suffix
); |
| 1619 } | 1648 } |
| 1620 | 1649 |
| 1621 PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC) | 1650 PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC) |
| (...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2209 } else if (localeIdMatchesLang(localeIdentifier, "lt")) { | 2238 } else if (localeIdMatchesLang(localeIdentifier, "lt")) { |
| 2210 // TODO(rob.buis) implement upper-casing rules for lt | 2239 // TODO(rob.buis) implement upper-casing rules for lt |
| 2211 // like in StringImpl::upper(locale). | 2240 // like in StringImpl::upper(locale). |
| 2212 } | 2241 } |
| 2213 } | 2242 } |
| 2214 | 2243 |
| 2215 return toUpper(c); | 2244 return toUpper(c); |
| 2216 } | 2245 } |
| 2217 | 2246 |
| 2218 } // namespace WTF | 2247 } // namespace WTF |
| OLD | NEW |