Index: chrome/renderer/spellchecker/spellcheck_worditerator.cc |
diff --git a/chrome/renderer/spellchecker/spellcheck_worditerator.cc b/chrome/renderer/spellchecker/spellcheck_worditerator.cc |
index 1297c5ab8f202afaefa6606f26724257f3e59de2..a84904293ea580f0988f91c1c5669c390794fd7a 100644 |
--- a/chrome/renderer/spellchecker/spellcheck_worditerator.cc |
+++ b/chrome/renderer/spellchecker/spellcheck_worditerator.cc |
@@ -10,6 +10,7 @@ |
#include <string> |
#include "base/basictypes.h" |
+#include "base/i18n/break_iterator.h" |
#include "base/logging.h" |
#include "base/strings/stringprintf.h" |
#include "base/strings/utf_string_conversions.h" |
@@ -299,10 +300,8 @@ bool SpellcheckCharAttribute::OutputDefault(UChar c, |
SpellcheckWordIterator::SpellcheckWordIterator() |
: text_(NULL), |
- length_(0), |
- position_(UBRK_DONE), |
attribute_(NULL), |
- iterator_(NULL) { |
+ iterator_() { |
} |
SpellcheckWordIterator::~SpellcheckWordIterator() { |
@@ -315,18 +314,22 @@ bool SpellcheckWordIterator::Initialize( |
// Create a custom ICU break iterator with empty text used in this object. (We |
// allow setting text later so we can re-use this iterator.) |
DCHECK(attribute); |
- UErrorCode open_status = U_ZERO_ERROR; |
- UParseError parse_status; |
- base::string16 rule(attribute->GetRuleSet(allow_contraction)); |
+ const base::string16 rule(attribute->GetRuleSet(allow_contraction)); |
// If there is no rule set, the attributes were invalid. |
if (rule.empty()) |
return false; |
- iterator_ = ubrk_openRules(rule.c_str(), rule.length(), NULL, 0, |
- &parse_status, &open_status); |
- if (U_FAILURE(open_status)) |
+ scoped_ptr<base::i18n::BreakIterator> iterator( |
+ new base::i18n::BreakIterator(base::string16(), rule)); |
+ if (!iterator->Init()) { |
+ // Since we're not passing in any text, the only reason this could fail |
+ // is if we fail to parse the rules. Since the rules are hardcoded, |
+ // that would be a bug in this class. |
+ NOTREACHED() << "failed to open iterator (broken rules)"; |
return false; |
+ } |
+ iterator_ = iterator.Pass(); |
// Set the character attributes so we can normalize the words extracted by |
// this iterator. |
@@ -335,7 +338,7 @@ bool SpellcheckWordIterator::Initialize( |
} |
bool SpellcheckWordIterator::IsInitialized() const { |
- // Return true if we have an ICU custom iterator. |
+ // Return true iff we have an iterator. |
return !!iterator_; |
} |
@@ -343,66 +346,51 @@ bool SpellcheckWordIterator::SetText(const base::char16* text, size_t length) { |
DCHECK(!!iterator_); |
// Set the text to be split by this iterator. |
- UErrorCode status = U_ZERO_ERROR; |
- ubrk_setText(iterator_, text, length, &status); |
- if (U_FAILURE(status)) |
- return false; |
- |
- // Retrieve the position to the first word in this text. We return false if |
- // this text does not have any words. (For example, The input text consists |
- // only of Chinese characters while the spellchecker language is English.) |
- position_ = ubrk_first(iterator_); |
- if (position_ == UBRK_DONE) |
+ if (!iterator_->SetText(text, length)) { |
+ LOG(ERROR) << "failed to set text"; |
return false; |
+ } |
text_ = text; |
- length_ = static_cast<int>(length); |
return true; |
} |
bool SpellcheckWordIterator::GetNextWord(base::string16* word_string, |
int* word_start, |
int* word_length) { |
- DCHECK(!!text_ && length_ > 0); |
+ DCHECK(!!text_); |
word_string->clear(); |
*word_start = 0; |
*word_length = 0; |
- if (!text_ || position_ == UBRK_DONE) |
+ if (!text_) { |
return false; |
+ } |
// Find a word that can be checked for spelling. Our rule sets filter out |
// invalid words (e.g. numbers and characters not supported by the |
// spellchecker language) so this ubrk_getRuleStatus() call returns |
// UBRK_WORD_NONE when this iterator finds an invalid word. So, we skip such |
// words until we can find a valid word or reach the end of the input string. |
- int next = ubrk_next(iterator_); |
- while (next != UBRK_DONE) { |
- if (ubrk_getRuleStatus(iterator_) != UBRK_WORD_NONE) { |
- if (Normalize(position_, next - position_, word_string)) { |
- *word_start = position_; |
- *word_length = next - position_; |
- position_ = next; |
+ while (iterator_->Advance()) { |
+ const size_t start = iterator_->prev(); |
+ const size_t length = iterator_->pos() - start; |
+ if (iterator_->IsWord()) { |
+ if (Normalize(start, length, word_string)) { |
+ *word_start = start; |
+ *word_length = length; |
return true; |
} |
} |
- position_ = next; |
- next = ubrk_next(iterator_); |
} |
- // There aren't any more words in the given text. Set the position to |
- // UBRK_DONE to prevent from calling ubrk_next() next time when this function |
- // is called. |
- position_ = UBRK_DONE; |
+ // There aren't any more words in the given text. |
return false; |
} |
void SpellcheckWordIterator::Reset() { |
- if (iterator_) { |
- ubrk_close(iterator_); |
- iterator_ = NULL; |
- } |
+ iterator_.reset(); |
} |
bool SpellcheckWordIterator::Normalize(int input_start, |