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 |