Chromium Code Reviews| Index: Source/platform/text/TextBreakIteratorICU.cpp |
| diff --git a/Source/platform/text/TextBreakIteratorICU.cpp b/Source/platform/text/TextBreakIteratorICU.cpp |
| index fba68c0876f2e835196a8c3e674cf1f034a77cf3..0890d80d749b7702239797b0dc1763e7a7968a07 100644 |
| --- a/Source/platform/text/TextBreakIteratorICU.cpp |
| +++ b/Source/platform/text/TextBreakIteratorICU.cpp |
| @@ -49,9 +49,9 @@ public: |
| static PassOwnPtr<LineBreakIteratorPool> create() { return adoptPtr(new LineBreakIteratorPool); } |
| - UBreakIterator* take(const AtomicString& locale) |
| + icu::BreakIterator* take(const AtomicString& locale) |
| { |
| - UBreakIterator* iterator = 0; |
| + icu::BreakIterator* iterator = 0; |
| for (size_t i = 0; i < m_pool.size(); ++i) { |
| if (m_pool[i].first == locale) { |
| iterator = m_pool[i].second; |
| @@ -63,16 +63,16 @@ public: |
| if (!iterator) { |
| UErrorCode openStatus = U_ZERO_ERROR; |
| bool localeIsEmpty = locale.isEmpty(); |
| - iterator = ubrk_open(UBRK_LINE, localeIsEmpty ? currentTextBreakLocaleID() : locale.string().utf8().data(), 0, 0, &openStatus); |
| + iterator = icu::BreakIterator::createLineInstance(localeIsEmpty ? icu::Locale(currentTextBreakLocaleID()) : icu::Locale(locale.string().utf8().data()), openStatus); |
| // locale comes from a web page and it can be invalid, leading ICU |
| // to fail, in which case we fall back to the default locale. |
| if (!localeIsEmpty && U_FAILURE(openStatus)) { |
| openStatus = U_ZERO_ERROR; |
| - iterator = ubrk_open(UBRK_LINE, currentTextBreakLocaleID(), 0, 0, &openStatus); |
| + iterator = icu::BreakIterator::createLineInstance(icu::Locale(currentTextBreakLocaleID()), openStatus); |
| } |
| if (U_FAILURE(openStatus)) { |
| - LOG_ERROR("ubrk_open failed with status %d", openStatus); |
| + LOG_ERROR("icu::BreakIterator construction failed with status %d", openStatus); |
| return 0; |
| } |
| } |
| @@ -82,12 +82,12 @@ public: |
| return iterator; |
| } |
| - void put(UBreakIterator* iterator) |
| + void put(icu::BreakIterator* iterator) |
| { |
| ASSERT_ARG(iterator, m_vendedIterators.contains(iterator)); |
| if (m_pool.size() == capacity) { |
| - ubrk_close(m_pool[0].second); |
| + delete(m_pool[0].second); |
| m_pool.remove(0); |
| } |
| @@ -99,10 +99,10 @@ private: |
| static const size_t capacity = 4; |
| - typedef pair<AtomicString, UBreakIterator*> Entry; |
| + typedef pair<AtomicString, icu::BreakIterator*> Entry; |
| typedef Vector<Entry, capacity> Pool; |
| Pool m_pool; |
| - HashMap<UBreakIterator*, AtomicString> m_vendedIterators; |
| + HashMap<icu::BreakIterator*, AtomicString> m_vendedIterators; |
| friend WTF::ThreadSpecific<LineBreakIteratorPool>::operator LineBreakIteratorPool*(); |
| }; |
| @@ -486,31 +486,16 @@ static UText* textOpenUTF16(UText* text, const UChar* string, unsigned length, c |
| static UText emptyText = UTEXT_INITIALIZER; |
| -static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator*& iterator, UBreakIteratorType type, const UChar* string, int length) |
| -{ |
| - if (!string) |
| - return 0; |
| - |
| - iterator = ensureIterator(createdIterator, iterator, type); |
| - if (!iterator) |
| - return 0; |
| - |
| - UErrorCode setTextStatus = U_ZERO_ERROR; |
| - ubrk_setText(reinterpret_cast<UBreakIterator*>(iterator), string, length, &setTextStatus); |
| - if (U_FAILURE(setTextStatus)) |
| - return 0; |
| - |
| - return iterator; |
| -} |
| - |
| -static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator*& iterator, UBreakIteratorType type, const LChar* string, int length) |
| +static TextBreakIterator* wordBreakIterator(const LChar* string, int length) |
| { |
| - if (!string) |
| - return 0; |
| - |
| - iterator = ensureIterator(createdIterator, iterator, type); |
| - if (!iterator) |
| - return 0; |
| + UErrorCode errorCode = U_ZERO_ERROR; |
| + static TextBreakIterator* breakIter = 0; |
| + if (!breakIter) { |
| + breakIter = icu::BreakIterator::createWordInstance(icu::Locale(currentTextBreakLocaleID()), errorCode); |
| + ASSERT_WITH_MESSAGE(U_SUCCESS(errorCode), "ICU could not open a break iterator: %s (%d)", u_errorName(errorCode), errorCode); |
| + if (!breakIter) |
| + return 0; |
| + } |
| UTextWithBuffer textLocal; |
| textLocal.text = emptyText; |
| @@ -525,32 +510,37 @@ static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator |
| } |
| UErrorCode setTextStatus = U_ZERO_ERROR; |
| - ubrk_setUText(reinterpret_cast<UBreakIterator*>(iterator), text, &setTextStatus); |
| - if (U_FAILURE(setTextStatus)) { |
| - LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus); |
| - // FIXME: Do we need to call utext_close(text) here? |
| - return 0; |
| - } |
| + breakIter->setText(text, setTextStatus); |
| + if (U_FAILURE(setTextStatus)) |
| + LOG_ERROR("BreakIterator::seText failed with status %d", setTextStatus); |
| utext_close(text); |
| - return iterator; |
| + return breakIter; |
| } |
| -static TextBreakIterator* wordBreakIterator(const LChar* string, int length) |
| +static void setText16(TextBreakIterator* iter, const UChar* string, int length) |
| { |
| - static bool createdWordBreakIterator8 = false; |
| - static TextBreakIterator* staticWordBreakIterator8; |
| - return setUpIterator(createdWordBreakIterator8, |
| - staticWordBreakIterator8, UBRK_WORD, string, length); |
| + UErrorCode errorCode = U_ZERO_ERROR; |
| + UText uText = UTEXT_INITIALIZER; |
| + utext_openUChars(&uText, string, length, &errorCode); |
| + if (U_FAILURE(errorCode)) |
| + return; |
| + iter->setText(&uText, errorCode); |
| } |
| TextBreakIterator* wordBreakIterator(const UChar* string, int length) |
| { |
| - static bool createdWordBreakIterator16 = false; |
| - static TextBreakIterator* staticWordBreakIterator16; |
| - return setUpIterator(createdWordBreakIterator16, |
| - staticWordBreakIterator16, UBRK_WORD, string, length); |
| + UErrorCode errorCode = U_ZERO_ERROR; |
| + static TextBreakIterator* breakIter = 0; |
| + if (!breakIter) { |
| + breakIter = icu::BreakIterator::createWordInstance(icu::Locale(currentTextBreakLocaleID()), errorCode); |
| + ASSERT_WITH_MESSAGE(U_SUCCESS(errorCode), "ICU could not open a break iterator: %s (%d)", u_errorName(errorCode), errorCode); |
| + if (!breakIter) |
| + return 0; |
| + } |
| + setText16(breakIter, string, length); |
| + return breakIter; |
| } |
| TextBreakIterator* wordBreakIterator(const String& string, int start, int length) |
| @@ -564,7 +554,7 @@ TextBreakIterator* wordBreakIterator(const String& string, int start, int length |
| TextBreakIterator* acquireLineBreakIterator(const LChar* string, int length, const AtomicString& locale, const UChar* priorContext, unsigned priorContextLength) |
| { |
| - UBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale); |
| + TextBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale); |
| if (!iterator) |
| return 0; |
| @@ -581,21 +571,20 @@ TextBreakIterator* acquireLineBreakIterator(const LChar* string, int length, con |
| } |
| UErrorCode setTextStatus = U_ZERO_ERROR; |
| - ubrk_setUText(iterator, text, &setTextStatus); |
| + iterator->setText(text, setTextStatus); |
| if (U_FAILURE(setTextStatus)) { |
| - // FIXME: Do we need to call utext_close(text) here? |
| LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus); |
| return 0; |
| } |
| utext_close(text); |
| - return reinterpret_cast<TextBreakIterator*>(iterator); |
| + return iterator; |
| } |
| TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length, const AtomicString& locale, const UChar* priorContext, unsigned priorContextLength) |
| { |
| - UBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale); |
| + TextBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale); |
| if (!iterator) |
| return 0; |
| @@ -609,23 +598,22 @@ TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length, con |
| } |
| UErrorCode setTextStatus = U_ZERO_ERROR; |
| - ubrk_setUText(iterator, text, &setTextStatus); |
| + iterator->setText(text, setTextStatus); |
| if (U_FAILURE(setTextStatus)) { |
| - // FIXME: Do we need to call utext_close(text) here? |
| LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus); |
| return 0; |
| } |
| utext_close(text); |
| - return reinterpret_cast<TextBreakIterator*>(iterator); |
| + return iterator; |
| } |
| void releaseLineBreakIterator(TextBreakIterator* iterator) |
| { |
| ASSERT_ARG(iterator, iterator); |
| - LineBreakIteratorPool::sharedPool().put(reinterpret_cast<UBreakIterator*>(iterator)); |
| + LineBreakIteratorPool::sharedPool().put(iterator); |
| } |
| static TextBreakIterator* nonSharedCharacterBreakIterator; |
| @@ -676,7 +664,13 @@ void NonSharedCharacterBreakIterator::createIteratorForBuffer(const UChar* buffe |
| { |
| m_iterator = nonSharedCharacterBreakIterator; |
| bool createdIterator = m_iterator && compareAndSwapNonSharedCharacterBreakIterator(m_iterator, 0); |
| - m_iterator = setUpIterator(createdIterator, m_iterator, UBRK_CHARACTER, buffer, length); |
| + if (!createdIterator) { |
| + UErrorCode errorCode = U_ZERO_ERROR; |
| + m_iterator = icu::BreakIterator::createCharacterInstance(icu::Locale(currentTextBreakLocaleID()), errorCode); |
| + ASSERT_WITH_MESSAGE(U_SUCCESS(errorCode), "ICU could not open a break iterator: %s (%d)", u_errorName(errorCode), errorCode); |
| + } |
| + |
| + setText16(m_iterator, buffer, length); |
| } |
| NonSharedCharacterBreakIterator::~NonSharedCharacterBreakIterator() |
| @@ -684,13 +678,13 @@ NonSharedCharacterBreakIterator::~NonSharedCharacterBreakIterator() |
| if (m_is8Bit) |
| return; |
| if (!compareAndSwapNonSharedCharacterBreakIterator(0, m_iterator)) |
| - ubrk_close(reinterpret_cast<UBreakIterator*>(m_iterator)); |
| + delete m_iterator; |
| } |
| int NonSharedCharacterBreakIterator::next() |
| { |
| if (!m_is8Bit) |
| - return textBreakNext(m_iterator); |
| + return m_iterator->next(); |
| if (m_offset >= m_length) |
| return TextBreakDone; |
| @@ -702,21 +696,21 @@ int NonSharedCharacterBreakIterator::next() |
| int NonSharedCharacterBreakIterator::current() |
| { |
| if (!m_is8Bit) |
| - return textBreakCurrent(m_iterator); |
| + return m_iterator->current(); |
| return m_offset; |
| } |
| bool NonSharedCharacterBreakIterator::isBreak(int offset) const |
| { |
| if (!m_is8Bit) |
| - return isTextBreak(m_iterator, offset); |
| + return m_iterator->isBoundary(offset); |
| return !isLFAfterCR(offset); |
| } |
| int NonSharedCharacterBreakIterator::preceding(int offset) const |
| { |
| if (!m_is8Bit) |
| - return textBreakPreceding(m_iterator, offset); |
| + return m_iterator->preceding(offset); |
| if (offset <= 0) |
| return TextBreakDone; |
| if (isLFAfterCR(offset)) |
| @@ -727,7 +721,7 @@ int NonSharedCharacterBreakIterator::preceding(int offset) const |
| int NonSharedCharacterBreakIterator::following(int offset) const |
| { |
| if (!m_is8Bit) |
| - return textBreakFollowing(m_iterator, offset); |
| + return m_iterator->following(offset); |
| if (static_cast<unsigned>(offset) >= m_length) |
| return TextBreakDone; |
| return offset + clusterLengthStartingAt(offset); |
| @@ -735,81 +729,44 @@ int NonSharedCharacterBreakIterator::following(int offset) const |
| TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) |
| { |
| - static bool createdSentenceBreakIterator = false; |
| - static TextBreakIterator* staticSentenceBreakIterator; |
| - return setUpIterator(createdSentenceBreakIterator, |
| - staticSentenceBreakIterator, UBRK_SENTENCE, string, length); |
| -} |
| - |
| -int textBreakFirst(TextBreakIterator* iterator) |
| -{ |
| - return ubrk_first(reinterpret_cast<UBreakIterator*>(iterator)); |
| -} |
| - |
| -int textBreakLast(TextBreakIterator* iterator) |
| -{ |
| - return ubrk_last(reinterpret_cast<UBreakIterator*>(iterator)); |
| -} |
| - |
| -int textBreakNext(TextBreakIterator* iterator) |
| -{ |
| - return ubrk_next(reinterpret_cast<UBreakIterator*>(iterator)); |
| -} |
| - |
| -int textBreakPrevious(TextBreakIterator* iterator) |
| -{ |
| - return ubrk_previous(reinterpret_cast<UBreakIterator*>(iterator)); |
| -} |
| - |
| -int textBreakPreceding(TextBreakIterator* iterator, int pos) |
| -{ |
| - return ubrk_preceding(reinterpret_cast<UBreakIterator*>(iterator), pos); |
| -} |
| - |
| -int textBreakFollowing(TextBreakIterator* iterator, int pos) |
| -{ |
| - return ubrk_following(reinterpret_cast<UBreakIterator*>(iterator), pos); |
| -} |
| - |
| -int textBreakCurrent(TextBreakIterator* iterator) |
| -{ |
| - return ubrk_current(reinterpret_cast<UBreakIterator*>(iterator)); |
| -} |
| + UErrorCode openStatus = U_ZERO_ERROR; |
| + static TextBreakIterator* iterator = 0; |
| + if (!iterator) { |
| + iterator = icu::BreakIterator::createSentenceInstance(icu::Locale(currentTextBreakLocaleID()), openStatus); |
| + ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus); |
| + if (!iterator) |
| + return 0; |
| + } |
| -bool isTextBreak(TextBreakIterator* iterator, int position) |
| -{ |
| - return ubrk_isBoundary(reinterpret_cast<UBreakIterator*>(iterator), position); |
| + setText16(iterator, string, length); |
| + return iterator; |
| } |
| bool isWordTextBreak(TextBreakIterator* iterator) |
| { |
| - int ruleStatus = ubrk_getRuleStatus(reinterpret_cast<UBreakIterator*>(iterator)); |
| + int ruleStatus = iterator->getRuleStatus(); |
|
jungshik at Google
2013/10/11 20:18:30
With ICU 51 or earlier (without a patch to add get
|
| return ruleStatus != UBRK_WORD_NONE; |
| } |
| -static TextBreakIterator* setUpIteratorWithRules(bool& createdIterator, TextBreakIterator*& iterator, |
| - const char* breakRules, const UChar* string, int length) |
| +static TextBreakIterator* setUpIteratorWithRules(const char* breakRules, const UChar* string, int length) |
| { |
| if (!string) |
| return 0; |
| - if (!createdIterator) { |
| + static TextBreakIterator* iterator = 0; |
| + if (!iterator) { |
| UParseError parseStatus; |
| UErrorCode openStatus = U_ZERO_ERROR; |
| Vector<UChar> rules; |
| String(breakRules).appendTo(rules); |
| - iterator = reinterpret_cast<TextBreakIterator*>(ubrk_openRules(rules.data(), rules.size(), 0, 0, &parseStatus, &openStatus)); |
| - createdIterator = true; |
| + |
| + iterator = new icu::RuleBasedBreakIterator(icu::UnicodeString(rules.data(), rules.size()), parseStatus, openStatus); |
| ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus); |
| + if (!iterator) |
| + return 0; |
| } |
| - if (!iterator) |
| - return 0; |
| - |
| - UErrorCode setTextStatus = U_ZERO_ERROR; |
| - ubrk_setText(reinterpret_cast<UBreakIterator*>(iterator), string, length, &setTextStatus); |
| - if (U_FAILURE(setTextStatus)) |
| - return 0; |
| + setText16(iterator, string, length); |
| return iterator; |
| } |
| @@ -897,9 +854,8 @@ TextBreakIterator* cursorMovementIterator(const UChar* string, int length) |
| "$Mal1 $MalV $Mal0;" // Malayalam Virama (backward) |
| "!!safe_reverse;" |
| "!!safe_forward;"; |
| - static bool createdCursorMovementIterator = false; |
| - static TextBreakIterator* staticCursorMovementIterator; |
| - return setUpIteratorWithRules(createdCursorMovementIterator, staticCursorMovementIterator, kRules, string, length); |
| + |
| + return setUpIteratorWithRules(kRules, string, length); |
| } |
| } |