virtual size_t Prev(IterType what) { int32_t pos; switch (what) { case ITER_CHARACTER: pos = this->char_itr->previous(); break; case ITER_WORD: pos = this->word_itr->preceding(this->char_itr->current()); /* The ICU word iterator considers both the start and the end of a word a valid * break point, but we only want word starts. Move to the previous location in * case the new position points to whitespace. */ while (pos != icu::BreakIterator::DONE && IsWhitespace(Utf16DecodeChar((const uint16 *)&this->utf16_str[pos]))) { int32_t new_pos = this->word_itr->previous(); /* Don't set it to DONE if it was valid before. Otherwise we'll return END * even though the iterator wasn't at the start of the string before. */ if (new_pos == icu::BreakIterator::DONE) break; pos = new_pos; } this->char_itr->isBoundary(pos); break; default: NOT_REACHED(); } return pos == icu::BreakIterator::DONE ? END : this->utf16_to_utf8[pos]; }
virtual size_t Next(IterType what) { int32_t pos; switch (what) { case ITER_CHARACTER: pos = this->char_itr->next(); break; case ITER_WORD: pos = this->word_itr->following(this->char_itr->current()); /* The ICU word iterator considers both the start and the end of a word a valid * break point, but we only want word starts. Move to the next location in * case the new position points to whitespace. */ while (pos != icu::BreakIterator::DONE && IsWhitespace(Utf16DecodeChar((const uint16 *)&this->utf16_str[pos]))) pos = this->word_itr->next(); this->char_itr->isBoundary(pos); break; default: NOT_REACHED(); } return pos == icu::BreakIterator::DONE ? END : this->utf16_to_utf8[pos]; }