| 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 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 return U16_GET_SUPPLEMENTARY(characters16()[i], characters16()[i + 1]); | 495 return U16_GET_SUPPLEMENTARY(characters16()[i], characters16()[i + 1]); |
| 496 return 0; | 496 return 0; |
| 497 } | 497 } |
| 498 | 498 |
| 499 PassRefPtr<StringImpl> StringImpl::lower() | 499 PassRefPtr<StringImpl> StringImpl::lower() |
| 500 { | 500 { |
| 501 // Note: This is a hot function in the Dromaeo benchmark, specifically the | 501 // Note: This is a hot function in the Dromaeo benchmark, specifically the |
| 502 // no-op code path up through the first 'return' statement. | 502 // no-op code path up through the first 'return' statement. |
| 503 | 503 |
| 504 // First scan the string for uppercase and non-ASCII characters: | 504 // First scan the string for uppercase and non-ASCII characters: |
| 505 bool noUpper = true; | |
| 506 UChar ored = 0; | |
| 507 if (is8Bit()) { | 505 if (is8Bit()) { |
| 508 const LChar* end = characters8() + m_length; | 506 unsigned firstIndexToBeLowered = m_length; |
| 509 for (const LChar* chp = characters8(); chp != end; ++chp) { | 507 for (unsigned i = 0; i < m_length; ++i) { |
| 510 if (UNLIKELY(isASCIIUpper(*chp))) | 508 LChar ch = characters8()[i]; |
| 511 noUpper = false; | 509 if (UNLIKELY(isASCIIUpper(ch) || ch & ~0x7F)) { |
| 512 ored |= *chp; | 510 firstIndexToBeLowered = i; |
| 511 break; |
| 512 } |
| 513 } | 513 } |
| 514 |
| 514 // Nothing to do if the string is all ASCII with no uppercase. | 515 // Nothing to do if the string is all ASCII with no uppercase. |
| 515 if (noUpper && !(ored & ~0x7F)) | 516 if (firstIndexToBeLowered == m_length) |
| 516 return this; | 517 return this; |
| 517 | 518 |
| 518 RELEASE_ASSERT(m_length <= static_cast<unsigned>(numeric_limits<int32_t>
::max())); | 519 LChar* data8; |
| 519 int32_t length = m_length; | 520 RefPtr<StringImpl> newImpl = createUninitialized(m_length, data8); |
| 521 memcpy(data8, characters8(), firstIndexToBeLowered); |
| 520 | 522 |
| 521 LChar* data8; | 523 for (unsigned i = firstIndexToBeLowered; i < m_length; ++i) { |
| 522 RefPtr<StringImpl> newImpl = createUninitialized(length, data8); | 524 LChar ch = characters8()[i]; |
| 523 | 525 data8[i] = UNLIKELY(ch & ~0x7F) ? static_cast<LChar>(Unicode::toLowe
r(ch)) |
| 524 if (!(ored & ~0x7F)) { | 526 : toASCIILower(ch); |
| 525 for (int32_t i = 0; i < length; ++i) | |
| 526 data8[i] = toASCIILower(characters8()[i]); | |
| 527 | |
| 528 return newImpl.release(); | |
| 529 } | 527 } |
| 530 | 528 |
| 531 // Do a slower implementation for cases that include non-ASCII Latin-1 c
haracters. | |
| 532 for (int32_t i = 0; i < length; ++i) | |
| 533 data8[i] = static_cast<LChar>(Unicode::toLower(characters8()[i])); | |
| 534 | |
| 535 return newImpl.release(); | 529 return newImpl.release(); |
| 536 } | 530 } |
| 537 | 531 |
| 532 bool noUpper = true; |
| 533 UChar ored = 0; |
| 534 |
| 538 const UChar* end = characters16() + m_length; | 535 const UChar* end = characters16() + m_length; |
| 539 for (const UChar* chp = characters16(); chp != end; ++chp) { | 536 for (const UChar* chp = characters16(); chp != end; ++chp) { |
| 540 if (UNLIKELY(isASCIIUpper(*chp))) | 537 if (UNLIKELY(isASCIIUpper(*chp))) |
| 541 noUpper = false; | 538 noUpper = false; |
| 542 ored |= *chp; | 539 ored |= *chp; |
| 543 } | 540 } |
| 544 // Nothing to do if the string is all ASCII with no uppercase. | 541 // Nothing to do if the string is all ASCII with no uppercase. |
| 545 if (noUpper && !(ored & ~0x7F)) | 542 if (noUpper && !(ored & ~0x7F)) |
| 546 return this; | 543 return this; |
| 547 | 544 |
| (...skipping 1575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2123 } else if (localeIdMatchesLang(localeIdentifier, "lt")) { | 2120 } else if (localeIdMatchesLang(localeIdentifier, "lt")) { |
| 2124 // TODO(rob.buis) implement upper-casing rules for lt | 2121 // TODO(rob.buis) implement upper-casing rules for lt |
| 2125 // like in StringImpl::upper(locale). | 2122 // like in StringImpl::upper(locale). |
| 2126 } | 2123 } |
| 2127 } | 2124 } |
| 2128 | 2125 |
| 2129 return toUpper(c); | 2126 return toUpper(c); |
| 2130 } | 2127 } |
| 2131 | 2128 |
| 2132 } // namespace WTF | 2129 } // namespace WTF |
| OLD | NEW |