12e5b6d6dSopenharmony_ci// © 2016 and later: Unicode, Inc. and others. 22e5b6d6dSopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html 32e5b6d6dSopenharmony_ci/* 42e5b6d6dSopenharmony_ci********************************************************************** 52e5b6d6dSopenharmony_ci* Copyright (C) 2001-2014 IBM and others. All rights reserved. 62e5b6d6dSopenharmony_ci********************************************************************** 72e5b6d6dSopenharmony_ci* Date Name Description 82e5b6d6dSopenharmony_ci* 03/22/2000 helena Creation. 92e5b6d6dSopenharmony_ci********************************************************************** 102e5b6d6dSopenharmony_ci*/ 112e5b6d6dSopenharmony_ci 122e5b6d6dSopenharmony_ci#include "unicode/utypes.h" 132e5b6d6dSopenharmony_ci 142e5b6d6dSopenharmony_ci#if !UCONFIG_NO_COLLATION && !UCONFIG_NO_BREAK_ITERATION 152e5b6d6dSopenharmony_ci 162e5b6d6dSopenharmony_ci#include "unicode/stsearch.h" 172e5b6d6dSopenharmony_ci#include "usrchimp.h" 182e5b6d6dSopenharmony_ci#include "cmemory.h" 192e5b6d6dSopenharmony_ci 202e5b6d6dSopenharmony_ciU_NAMESPACE_BEGIN 212e5b6d6dSopenharmony_ci 222e5b6d6dSopenharmony_ciUOBJECT_DEFINE_RTTI_IMPLEMENTATION(StringSearch) 232e5b6d6dSopenharmony_ci 242e5b6d6dSopenharmony_ci// public constructors and destructors ----------------------------------- 252e5b6d6dSopenharmony_ci 262e5b6d6dSopenharmony_ciStringSearch::StringSearch(const UnicodeString &pattern, 272e5b6d6dSopenharmony_ci const UnicodeString &text, 282e5b6d6dSopenharmony_ci const Locale &locale, 292e5b6d6dSopenharmony_ci BreakIterator *breakiter, 302e5b6d6dSopenharmony_ci UErrorCode &status) : 312e5b6d6dSopenharmony_ci SearchIterator(text, breakiter), 322e5b6d6dSopenharmony_ci m_pattern_(pattern) 332e5b6d6dSopenharmony_ci{ 342e5b6d6dSopenharmony_ci if (U_FAILURE(status)) { 352e5b6d6dSopenharmony_ci m_strsrch_ = NULL; 362e5b6d6dSopenharmony_ci return; 372e5b6d6dSopenharmony_ci } 382e5b6d6dSopenharmony_ci 392e5b6d6dSopenharmony_ci m_strsrch_ = usearch_open(m_pattern_.getBuffer(), m_pattern_.length(), 402e5b6d6dSopenharmony_ci m_text_.getBuffer(), m_text_.length(), 412e5b6d6dSopenharmony_ci locale.getName(), (UBreakIterator *)breakiter, 422e5b6d6dSopenharmony_ci &status); 432e5b6d6dSopenharmony_ci uprv_free(m_search_); 442e5b6d6dSopenharmony_ci m_search_ = NULL; 452e5b6d6dSopenharmony_ci 462e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 472e5b6d6dSopenharmony_ci // m_search_ has been created by the base SearchIterator class 482e5b6d6dSopenharmony_ci m_search_ = m_strsrch_->search; 492e5b6d6dSopenharmony_ci } 502e5b6d6dSopenharmony_ci} 512e5b6d6dSopenharmony_ci 522e5b6d6dSopenharmony_ciStringSearch::StringSearch(const UnicodeString &pattern, 532e5b6d6dSopenharmony_ci const UnicodeString &text, 542e5b6d6dSopenharmony_ci RuleBasedCollator *coll, 552e5b6d6dSopenharmony_ci BreakIterator *breakiter, 562e5b6d6dSopenharmony_ci UErrorCode &status) : 572e5b6d6dSopenharmony_ci SearchIterator(text, breakiter), 582e5b6d6dSopenharmony_ci m_pattern_(pattern) 592e5b6d6dSopenharmony_ci{ 602e5b6d6dSopenharmony_ci if (U_FAILURE(status)) { 612e5b6d6dSopenharmony_ci m_strsrch_ = NULL; 622e5b6d6dSopenharmony_ci return; 632e5b6d6dSopenharmony_ci } 642e5b6d6dSopenharmony_ci if (coll == NULL) { 652e5b6d6dSopenharmony_ci status = U_ILLEGAL_ARGUMENT_ERROR; 662e5b6d6dSopenharmony_ci m_strsrch_ = NULL; 672e5b6d6dSopenharmony_ci return; 682e5b6d6dSopenharmony_ci } 692e5b6d6dSopenharmony_ci m_strsrch_ = usearch_openFromCollator(m_pattern_.getBuffer(), 702e5b6d6dSopenharmony_ci m_pattern_.length(), 712e5b6d6dSopenharmony_ci m_text_.getBuffer(), 722e5b6d6dSopenharmony_ci m_text_.length(), coll->toUCollator(), 732e5b6d6dSopenharmony_ci (UBreakIterator *)breakiter, 742e5b6d6dSopenharmony_ci &status); 752e5b6d6dSopenharmony_ci uprv_free(m_search_); 762e5b6d6dSopenharmony_ci m_search_ = NULL; 772e5b6d6dSopenharmony_ci 782e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 792e5b6d6dSopenharmony_ci // m_search_ has been created by the base SearchIterator class 802e5b6d6dSopenharmony_ci m_search_ = m_strsrch_->search; 812e5b6d6dSopenharmony_ci } 822e5b6d6dSopenharmony_ci} 832e5b6d6dSopenharmony_ci 842e5b6d6dSopenharmony_ciStringSearch::StringSearch(const UnicodeString &pattern, 852e5b6d6dSopenharmony_ci CharacterIterator &text, 862e5b6d6dSopenharmony_ci const Locale &locale, 872e5b6d6dSopenharmony_ci BreakIterator *breakiter, 882e5b6d6dSopenharmony_ci UErrorCode &status) : 892e5b6d6dSopenharmony_ci SearchIterator(text, breakiter), 902e5b6d6dSopenharmony_ci m_pattern_(pattern) 912e5b6d6dSopenharmony_ci{ 922e5b6d6dSopenharmony_ci if (U_FAILURE(status)) { 932e5b6d6dSopenharmony_ci m_strsrch_ = NULL; 942e5b6d6dSopenharmony_ci return; 952e5b6d6dSopenharmony_ci } 962e5b6d6dSopenharmony_ci m_strsrch_ = usearch_open(m_pattern_.getBuffer(), m_pattern_.length(), 972e5b6d6dSopenharmony_ci m_text_.getBuffer(), m_text_.length(), 982e5b6d6dSopenharmony_ci locale.getName(), (UBreakIterator *)breakiter, 992e5b6d6dSopenharmony_ci &status); 1002e5b6d6dSopenharmony_ci uprv_free(m_search_); 1012e5b6d6dSopenharmony_ci m_search_ = NULL; 1022e5b6d6dSopenharmony_ci 1032e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 1042e5b6d6dSopenharmony_ci // m_search_ has been created by the base SearchIterator class 1052e5b6d6dSopenharmony_ci m_search_ = m_strsrch_->search; 1062e5b6d6dSopenharmony_ci } 1072e5b6d6dSopenharmony_ci} 1082e5b6d6dSopenharmony_ci 1092e5b6d6dSopenharmony_ciStringSearch::StringSearch(const UnicodeString &pattern, 1102e5b6d6dSopenharmony_ci CharacterIterator &text, 1112e5b6d6dSopenharmony_ci RuleBasedCollator *coll, 1122e5b6d6dSopenharmony_ci BreakIterator *breakiter, 1132e5b6d6dSopenharmony_ci UErrorCode &status) : 1142e5b6d6dSopenharmony_ci SearchIterator(text, breakiter), 1152e5b6d6dSopenharmony_ci m_pattern_(pattern) 1162e5b6d6dSopenharmony_ci{ 1172e5b6d6dSopenharmony_ci if (U_FAILURE(status)) { 1182e5b6d6dSopenharmony_ci m_strsrch_ = NULL; 1192e5b6d6dSopenharmony_ci return; 1202e5b6d6dSopenharmony_ci } 1212e5b6d6dSopenharmony_ci if (coll == NULL) { 1222e5b6d6dSopenharmony_ci status = U_ILLEGAL_ARGUMENT_ERROR; 1232e5b6d6dSopenharmony_ci m_strsrch_ = NULL; 1242e5b6d6dSopenharmony_ci return; 1252e5b6d6dSopenharmony_ci } 1262e5b6d6dSopenharmony_ci m_strsrch_ = usearch_openFromCollator(m_pattern_.getBuffer(), 1272e5b6d6dSopenharmony_ci m_pattern_.length(), 1282e5b6d6dSopenharmony_ci m_text_.getBuffer(), 1292e5b6d6dSopenharmony_ci m_text_.length(), coll->toUCollator(), 1302e5b6d6dSopenharmony_ci (UBreakIterator *)breakiter, 1312e5b6d6dSopenharmony_ci &status); 1322e5b6d6dSopenharmony_ci uprv_free(m_search_); 1332e5b6d6dSopenharmony_ci m_search_ = NULL; 1342e5b6d6dSopenharmony_ci 1352e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 1362e5b6d6dSopenharmony_ci // m_search_ has been created by the base SearchIterator class 1372e5b6d6dSopenharmony_ci m_search_ = m_strsrch_->search; 1382e5b6d6dSopenharmony_ci } 1392e5b6d6dSopenharmony_ci} 1402e5b6d6dSopenharmony_ci 1412e5b6d6dSopenharmony_ciStringSearch::StringSearch(const StringSearch &that) : 1422e5b6d6dSopenharmony_ci SearchIterator(that.m_text_, that.m_breakiterator_), 1432e5b6d6dSopenharmony_ci m_pattern_(that.m_pattern_) 1442e5b6d6dSopenharmony_ci{ 1452e5b6d6dSopenharmony_ci UErrorCode status = U_ZERO_ERROR; 1462e5b6d6dSopenharmony_ci 1472e5b6d6dSopenharmony_ci // Free m_search_ from the superclass 1482e5b6d6dSopenharmony_ci uprv_free(m_search_); 1492e5b6d6dSopenharmony_ci m_search_ = NULL; 1502e5b6d6dSopenharmony_ci 1512e5b6d6dSopenharmony_ci if (that.m_strsrch_ == NULL) { 1522e5b6d6dSopenharmony_ci // This was not a good copy 1532e5b6d6dSopenharmony_ci m_strsrch_ = NULL; 1542e5b6d6dSopenharmony_ci } 1552e5b6d6dSopenharmony_ci else { 1562e5b6d6dSopenharmony_ci // Make a deep copy 1572e5b6d6dSopenharmony_ci m_strsrch_ = usearch_openFromCollator(m_pattern_.getBuffer(), 1582e5b6d6dSopenharmony_ci m_pattern_.length(), 1592e5b6d6dSopenharmony_ci m_text_.getBuffer(), 1602e5b6d6dSopenharmony_ci m_text_.length(), 1612e5b6d6dSopenharmony_ci that.m_strsrch_->collator, 1622e5b6d6dSopenharmony_ci (UBreakIterator *)that.m_breakiterator_, 1632e5b6d6dSopenharmony_ci &status); 1642e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 1652e5b6d6dSopenharmony_ci // m_search_ has been created by the base SearchIterator class 1662e5b6d6dSopenharmony_ci m_search_ = m_strsrch_->search; 1672e5b6d6dSopenharmony_ci } 1682e5b6d6dSopenharmony_ci } 1692e5b6d6dSopenharmony_ci} 1702e5b6d6dSopenharmony_ci 1712e5b6d6dSopenharmony_ciStringSearch::~StringSearch() 1722e5b6d6dSopenharmony_ci{ 1732e5b6d6dSopenharmony_ci if (m_strsrch_ != NULL) { 1742e5b6d6dSopenharmony_ci usearch_close(m_strsrch_); 1752e5b6d6dSopenharmony_ci m_search_ = NULL; 1762e5b6d6dSopenharmony_ci } 1772e5b6d6dSopenharmony_ci} 1782e5b6d6dSopenharmony_ci 1792e5b6d6dSopenharmony_ciStringSearch * 1802e5b6d6dSopenharmony_ciStringSearch::clone() const { 1812e5b6d6dSopenharmony_ci return new StringSearch(*this); 1822e5b6d6dSopenharmony_ci} 1832e5b6d6dSopenharmony_ci 1842e5b6d6dSopenharmony_ci// operator overloading --------------------------------------------- 1852e5b6d6dSopenharmony_ciStringSearch & StringSearch::operator=(const StringSearch &that) 1862e5b6d6dSopenharmony_ci{ 1872e5b6d6dSopenharmony_ci if (this != &that) { 1882e5b6d6dSopenharmony_ci UErrorCode status = U_ZERO_ERROR; 1892e5b6d6dSopenharmony_ci m_text_ = that.m_text_; 1902e5b6d6dSopenharmony_ci m_breakiterator_ = that.m_breakiterator_; 1912e5b6d6dSopenharmony_ci m_pattern_ = that.m_pattern_; 1922e5b6d6dSopenharmony_ci // all m_search_ in the parent class is linked up with m_strsrch_ 1932e5b6d6dSopenharmony_ci usearch_close(m_strsrch_); 1942e5b6d6dSopenharmony_ci m_strsrch_ = usearch_openFromCollator(m_pattern_.getBuffer(), 1952e5b6d6dSopenharmony_ci m_pattern_.length(), 1962e5b6d6dSopenharmony_ci m_text_.getBuffer(), 1972e5b6d6dSopenharmony_ci m_text_.length(), 1982e5b6d6dSopenharmony_ci that.m_strsrch_->collator, 1992e5b6d6dSopenharmony_ci NULL, &status); 2002e5b6d6dSopenharmony_ci // Check null pointer 2012e5b6d6dSopenharmony_ci if (m_strsrch_ != NULL) { 2022e5b6d6dSopenharmony_ci m_search_ = m_strsrch_->search; 2032e5b6d6dSopenharmony_ci } 2042e5b6d6dSopenharmony_ci } 2052e5b6d6dSopenharmony_ci return *this; 2062e5b6d6dSopenharmony_ci} 2072e5b6d6dSopenharmony_ci 2082e5b6d6dSopenharmony_cibool StringSearch::operator==(const SearchIterator &that) const 2092e5b6d6dSopenharmony_ci{ 2102e5b6d6dSopenharmony_ci if (this == &that) { 2112e5b6d6dSopenharmony_ci return true; 2122e5b6d6dSopenharmony_ci } 2132e5b6d6dSopenharmony_ci if (SearchIterator::operator ==(that)) { 2142e5b6d6dSopenharmony_ci StringSearch &thatsrch = (StringSearch &)that; 2152e5b6d6dSopenharmony_ci return (this->m_pattern_ == thatsrch.m_pattern_ && 2162e5b6d6dSopenharmony_ci this->m_strsrch_->collator == thatsrch.m_strsrch_->collator); 2172e5b6d6dSopenharmony_ci } 2182e5b6d6dSopenharmony_ci return false; 2192e5b6d6dSopenharmony_ci} 2202e5b6d6dSopenharmony_ci 2212e5b6d6dSopenharmony_ci// public get and set methods ---------------------------------------- 2222e5b6d6dSopenharmony_ci 2232e5b6d6dSopenharmony_civoid StringSearch::setOffset(int32_t position, UErrorCode &status) 2242e5b6d6dSopenharmony_ci{ 2252e5b6d6dSopenharmony_ci // status checked in usearch_setOffset 2262e5b6d6dSopenharmony_ci usearch_setOffset(m_strsrch_, position, &status); 2272e5b6d6dSopenharmony_ci} 2282e5b6d6dSopenharmony_ci 2292e5b6d6dSopenharmony_ciint32_t StringSearch::getOffset(void) const 2302e5b6d6dSopenharmony_ci{ 2312e5b6d6dSopenharmony_ci return usearch_getOffset(m_strsrch_); 2322e5b6d6dSopenharmony_ci} 2332e5b6d6dSopenharmony_ci 2342e5b6d6dSopenharmony_civoid StringSearch::setText(const UnicodeString &text, UErrorCode &status) 2352e5b6d6dSopenharmony_ci{ 2362e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 2372e5b6d6dSopenharmony_ci m_text_ = text; 2382e5b6d6dSopenharmony_ci usearch_setText(m_strsrch_, text.getBuffer(), text.length(), &status); 2392e5b6d6dSopenharmony_ci } 2402e5b6d6dSopenharmony_ci} 2412e5b6d6dSopenharmony_ci 2422e5b6d6dSopenharmony_civoid StringSearch::setText(CharacterIterator &text, UErrorCode &status) 2432e5b6d6dSopenharmony_ci{ 2442e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 2452e5b6d6dSopenharmony_ci text.getText(m_text_); 2462e5b6d6dSopenharmony_ci usearch_setText(m_strsrch_, m_text_.getBuffer(), m_text_.length(), &status); 2472e5b6d6dSopenharmony_ci } 2482e5b6d6dSopenharmony_ci} 2492e5b6d6dSopenharmony_ci 2502e5b6d6dSopenharmony_ciRuleBasedCollator * StringSearch::getCollator() const 2512e5b6d6dSopenharmony_ci{ 2522e5b6d6dSopenharmony_ci // Note the const_cast. It would be cleaner if this const method returned a const collator. 2532e5b6d6dSopenharmony_ci return RuleBasedCollator::rbcFromUCollator(const_cast<UCollator *>(m_strsrch_->collator)); 2542e5b6d6dSopenharmony_ci} 2552e5b6d6dSopenharmony_ci 2562e5b6d6dSopenharmony_civoid StringSearch::setCollator(RuleBasedCollator *coll, UErrorCode &status) 2572e5b6d6dSopenharmony_ci{ 2582e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 2592e5b6d6dSopenharmony_ci usearch_setCollator(m_strsrch_, coll->toUCollator(), &status); 2602e5b6d6dSopenharmony_ci } 2612e5b6d6dSopenharmony_ci} 2622e5b6d6dSopenharmony_ci 2632e5b6d6dSopenharmony_civoid StringSearch::setPattern(const UnicodeString &pattern, 2642e5b6d6dSopenharmony_ci UErrorCode &status) 2652e5b6d6dSopenharmony_ci{ 2662e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 2672e5b6d6dSopenharmony_ci m_pattern_ = pattern; 2682e5b6d6dSopenharmony_ci usearch_setPattern(m_strsrch_, m_pattern_.getBuffer(), m_pattern_.length(), 2692e5b6d6dSopenharmony_ci &status); 2702e5b6d6dSopenharmony_ci } 2712e5b6d6dSopenharmony_ci} 2722e5b6d6dSopenharmony_ci 2732e5b6d6dSopenharmony_ciconst UnicodeString & StringSearch::getPattern() const 2742e5b6d6dSopenharmony_ci{ 2752e5b6d6dSopenharmony_ci return m_pattern_; 2762e5b6d6dSopenharmony_ci} 2772e5b6d6dSopenharmony_ci 2782e5b6d6dSopenharmony_ci// public methods ---------------------------------------------------- 2792e5b6d6dSopenharmony_ci 2802e5b6d6dSopenharmony_civoid StringSearch::reset() 2812e5b6d6dSopenharmony_ci{ 2822e5b6d6dSopenharmony_ci usearch_reset(m_strsrch_); 2832e5b6d6dSopenharmony_ci} 2842e5b6d6dSopenharmony_ci 2852e5b6d6dSopenharmony_ciStringSearch * StringSearch::safeClone() const 2862e5b6d6dSopenharmony_ci{ 2872e5b6d6dSopenharmony_ci UErrorCode status = U_ZERO_ERROR; 2882e5b6d6dSopenharmony_ci StringSearch *result = new StringSearch(m_pattern_, m_text_, 2892e5b6d6dSopenharmony_ci getCollator(), 2902e5b6d6dSopenharmony_ci m_breakiterator_, 2912e5b6d6dSopenharmony_ci status); 2922e5b6d6dSopenharmony_ci /* test for NULL */ 2932e5b6d6dSopenharmony_ci if (result == 0) { 2942e5b6d6dSopenharmony_ci status = U_MEMORY_ALLOCATION_ERROR; 2952e5b6d6dSopenharmony_ci return 0; 2962e5b6d6dSopenharmony_ci } 2972e5b6d6dSopenharmony_ci result->setOffset(getOffset(), status); 2982e5b6d6dSopenharmony_ci result->setMatchStart(m_strsrch_->search->matchedIndex); 2992e5b6d6dSopenharmony_ci result->setMatchLength(m_strsrch_->search->matchedLength); 3002e5b6d6dSopenharmony_ci if (U_FAILURE(status)) { 3012e5b6d6dSopenharmony_ci return NULL; 3022e5b6d6dSopenharmony_ci } 3032e5b6d6dSopenharmony_ci return result; 3042e5b6d6dSopenharmony_ci} 3052e5b6d6dSopenharmony_ci 3062e5b6d6dSopenharmony_ci// protected method ------------------------------------------------- 3072e5b6d6dSopenharmony_ci 3082e5b6d6dSopenharmony_ciint32_t StringSearch::handleNext(int32_t position, UErrorCode &status) 3092e5b6d6dSopenharmony_ci{ 3102e5b6d6dSopenharmony_ci // values passed here are already in the pre-shift position 3112e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 3122e5b6d6dSopenharmony_ci if (m_strsrch_->pattern.cesLength == 0) { 3132e5b6d6dSopenharmony_ci m_search_->matchedIndex = 3142e5b6d6dSopenharmony_ci m_search_->matchedIndex == USEARCH_DONE ? 3152e5b6d6dSopenharmony_ci getOffset() : m_search_->matchedIndex + 1; 3162e5b6d6dSopenharmony_ci m_search_->matchedLength = 0; 3172e5b6d6dSopenharmony_ci ucol_setOffset(m_strsrch_->textIter, m_search_->matchedIndex, 3182e5b6d6dSopenharmony_ci &status); 3192e5b6d6dSopenharmony_ci if (m_search_->matchedIndex == m_search_->textLength) { 3202e5b6d6dSopenharmony_ci m_search_->matchedIndex = USEARCH_DONE; 3212e5b6d6dSopenharmony_ci } 3222e5b6d6dSopenharmony_ci } 3232e5b6d6dSopenharmony_ci else { 3242e5b6d6dSopenharmony_ci // looking at usearch.cpp, this part is shifted out to 3252e5b6d6dSopenharmony_ci // StringSearch instead of SearchIterator because m_strsrch_ is 3262e5b6d6dSopenharmony_ci // not accessible in SearchIterator 3272e5b6d6dSopenharmony_ci#if 0 3282e5b6d6dSopenharmony_ci if (position + m_strsrch_->pattern.defaultShiftSize 3292e5b6d6dSopenharmony_ci > m_search_->textLength) { 3302e5b6d6dSopenharmony_ci setMatchNotFound(); 3312e5b6d6dSopenharmony_ci return USEARCH_DONE; 3322e5b6d6dSopenharmony_ci } 3332e5b6d6dSopenharmony_ci#endif 3342e5b6d6dSopenharmony_ci if (m_search_->matchedLength <= 0) { 3352e5b6d6dSopenharmony_ci // the flipping direction issue has already been handled 3362e5b6d6dSopenharmony_ci // in next() 3372e5b6d6dSopenharmony_ci // for boundary check purposes. this will ensure that the 3382e5b6d6dSopenharmony_ci // next match will not precede the current offset 3392e5b6d6dSopenharmony_ci // note search->matchedIndex will always be set to something 3402e5b6d6dSopenharmony_ci // in the code 3412e5b6d6dSopenharmony_ci m_search_->matchedIndex = position - 1; 3422e5b6d6dSopenharmony_ci } 3432e5b6d6dSopenharmony_ci 3442e5b6d6dSopenharmony_ci ucol_setOffset(m_strsrch_->textIter, position, &status); 3452e5b6d6dSopenharmony_ci 3462e5b6d6dSopenharmony_ci#if 0 3472e5b6d6dSopenharmony_ci for (;;) { 3482e5b6d6dSopenharmony_ci if (m_search_->isCanonicalMatch) { 3492e5b6d6dSopenharmony_ci // can't use exact here since extra accents are allowed. 3502e5b6d6dSopenharmony_ci usearch_handleNextCanonical(m_strsrch_, &status); 3512e5b6d6dSopenharmony_ci } 3522e5b6d6dSopenharmony_ci else { 3532e5b6d6dSopenharmony_ci usearch_handleNextExact(m_strsrch_, &status); 3542e5b6d6dSopenharmony_ci } 3552e5b6d6dSopenharmony_ci if (U_FAILURE(status)) { 3562e5b6d6dSopenharmony_ci return USEARCH_DONE; 3572e5b6d6dSopenharmony_ci } 3582e5b6d6dSopenharmony_ci if (m_breakiterator_ == NULL 3592e5b6d6dSopenharmony_ci#if !UCONFIG_NO_BREAK_ITERATION 3602e5b6d6dSopenharmony_ci || 3612e5b6d6dSopenharmony_ci m_search_->matchedIndex == USEARCH_DONE || 3622e5b6d6dSopenharmony_ci (m_breakiterator_->isBoundary(m_search_->matchedIndex) && 3632e5b6d6dSopenharmony_ci m_breakiterator_->isBoundary(m_search_->matchedIndex + 3642e5b6d6dSopenharmony_ci m_search_->matchedLength)) 3652e5b6d6dSopenharmony_ci#endif 3662e5b6d6dSopenharmony_ci ) { 3672e5b6d6dSopenharmony_ci if (m_search_->matchedIndex == USEARCH_DONE) { 3682e5b6d6dSopenharmony_ci ucol_setOffset(m_strsrch_->textIter, 3692e5b6d6dSopenharmony_ci m_search_->textLength, &status); 3702e5b6d6dSopenharmony_ci } 3712e5b6d6dSopenharmony_ci else { 3722e5b6d6dSopenharmony_ci ucol_setOffset(m_strsrch_->textIter, 3732e5b6d6dSopenharmony_ci m_search_->matchedIndex, &status); 3742e5b6d6dSopenharmony_ci } 3752e5b6d6dSopenharmony_ci return m_search_->matchedIndex; 3762e5b6d6dSopenharmony_ci } 3772e5b6d6dSopenharmony_ci } 3782e5b6d6dSopenharmony_ci#else 3792e5b6d6dSopenharmony_ci // if m_strsrch_->breakIter is always the same as m_breakiterator_ 3802e5b6d6dSopenharmony_ci // then we don't need to check the match boundaries here because 3812e5b6d6dSopenharmony_ci // usearch_handleNextXXX will already have done it. 3822e5b6d6dSopenharmony_ci if (m_search_->isCanonicalMatch) { 3832e5b6d6dSopenharmony_ci // *could* actually use exact here 'cause no extra accents allowed... 3842e5b6d6dSopenharmony_ci usearch_handleNextCanonical(m_strsrch_, &status); 3852e5b6d6dSopenharmony_ci } else { 3862e5b6d6dSopenharmony_ci usearch_handleNextExact(m_strsrch_, &status); 3872e5b6d6dSopenharmony_ci } 3882e5b6d6dSopenharmony_ci 3892e5b6d6dSopenharmony_ci if (U_FAILURE(status)) { 3902e5b6d6dSopenharmony_ci return USEARCH_DONE; 3912e5b6d6dSopenharmony_ci } 3922e5b6d6dSopenharmony_ci 3932e5b6d6dSopenharmony_ci if (m_search_->matchedIndex == USEARCH_DONE) { 3942e5b6d6dSopenharmony_ci ucol_setOffset(m_strsrch_->textIter, m_search_->textLength, &status); 3952e5b6d6dSopenharmony_ci } else { 3962e5b6d6dSopenharmony_ci ucol_setOffset(m_strsrch_->textIter, m_search_->matchedIndex, &status); 3972e5b6d6dSopenharmony_ci } 3982e5b6d6dSopenharmony_ci 3992e5b6d6dSopenharmony_ci return m_search_->matchedIndex; 4002e5b6d6dSopenharmony_ci#endif 4012e5b6d6dSopenharmony_ci } 4022e5b6d6dSopenharmony_ci } 4032e5b6d6dSopenharmony_ci return USEARCH_DONE; 4042e5b6d6dSopenharmony_ci} 4052e5b6d6dSopenharmony_ci 4062e5b6d6dSopenharmony_ciint32_t StringSearch::handlePrev(int32_t position, UErrorCode &status) 4072e5b6d6dSopenharmony_ci{ 4082e5b6d6dSopenharmony_ci // values passed here are already in the pre-shift position 4092e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 4102e5b6d6dSopenharmony_ci if (m_strsrch_->pattern.cesLength == 0) { 4112e5b6d6dSopenharmony_ci m_search_->matchedIndex = 4122e5b6d6dSopenharmony_ci (m_search_->matchedIndex == USEARCH_DONE ? getOffset() : 4132e5b6d6dSopenharmony_ci m_search_->matchedIndex); 4142e5b6d6dSopenharmony_ci if (m_search_->matchedIndex == 0) { 4152e5b6d6dSopenharmony_ci setMatchNotFound(); 4162e5b6d6dSopenharmony_ci } 4172e5b6d6dSopenharmony_ci else { 4182e5b6d6dSopenharmony_ci m_search_->matchedIndex --; 4192e5b6d6dSopenharmony_ci ucol_setOffset(m_strsrch_->textIter, m_search_->matchedIndex, 4202e5b6d6dSopenharmony_ci &status); 4212e5b6d6dSopenharmony_ci m_search_->matchedLength = 0; 4222e5b6d6dSopenharmony_ci } 4232e5b6d6dSopenharmony_ci } 4242e5b6d6dSopenharmony_ci else { 4252e5b6d6dSopenharmony_ci // looking at usearch.cpp, this part is shifted out to 4262e5b6d6dSopenharmony_ci // StringSearch instead of SearchIterator because m_strsrch_ is 4272e5b6d6dSopenharmony_ci // not accessible in SearchIterator 4282e5b6d6dSopenharmony_ci#if 0 4292e5b6d6dSopenharmony_ci if (!m_search_->isOverlap && 4302e5b6d6dSopenharmony_ci position - m_strsrch_->pattern.defaultShiftSize < 0) { 4312e5b6d6dSopenharmony_ci setMatchNotFound(); 4322e5b6d6dSopenharmony_ci return USEARCH_DONE; 4332e5b6d6dSopenharmony_ci } 4342e5b6d6dSopenharmony_ci 4352e5b6d6dSopenharmony_ci for (;;) { 4362e5b6d6dSopenharmony_ci if (m_search_->isCanonicalMatch) { 4372e5b6d6dSopenharmony_ci // can't use exact here since extra accents are allowed. 4382e5b6d6dSopenharmony_ci usearch_handlePreviousCanonical(m_strsrch_, &status); 4392e5b6d6dSopenharmony_ci } 4402e5b6d6dSopenharmony_ci else { 4412e5b6d6dSopenharmony_ci usearch_handlePreviousExact(m_strsrch_, &status); 4422e5b6d6dSopenharmony_ci } 4432e5b6d6dSopenharmony_ci if (U_FAILURE(status)) { 4442e5b6d6dSopenharmony_ci return USEARCH_DONE; 4452e5b6d6dSopenharmony_ci } 4462e5b6d6dSopenharmony_ci if (m_breakiterator_ == NULL 4472e5b6d6dSopenharmony_ci#if !UCONFIG_NO_BREAK_ITERATION 4482e5b6d6dSopenharmony_ci || 4492e5b6d6dSopenharmony_ci m_search_->matchedIndex == USEARCH_DONE || 4502e5b6d6dSopenharmony_ci (m_breakiterator_->isBoundary(m_search_->matchedIndex) && 4512e5b6d6dSopenharmony_ci m_breakiterator_->isBoundary(m_search_->matchedIndex + 4522e5b6d6dSopenharmony_ci m_search_->matchedLength)) 4532e5b6d6dSopenharmony_ci#endif 4542e5b6d6dSopenharmony_ci ) { 4552e5b6d6dSopenharmony_ci return m_search_->matchedIndex; 4562e5b6d6dSopenharmony_ci } 4572e5b6d6dSopenharmony_ci } 4582e5b6d6dSopenharmony_ci#else 4592e5b6d6dSopenharmony_ci ucol_setOffset(m_strsrch_->textIter, position, &status); 4602e5b6d6dSopenharmony_ci 4612e5b6d6dSopenharmony_ci if (m_search_->isCanonicalMatch) { 4622e5b6d6dSopenharmony_ci // *could* use exact match here since extra accents *not* allowed! 4632e5b6d6dSopenharmony_ci usearch_handlePreviousCanonical(m_strsrch_, &status); 4642e5b6d6dSopenharmony_ci } else { 4652e5b6d6dSopenharmony_ci usearch_handlePreviousExact(m_strsrch_, &status); 4662e5b6d6dSopenharmony_ci } 4672e5b6d6dSopenharmony_ci 4682e5b6d6dSopenharmony_ci if (U_FAILURE(status)) { 4692e5b6d6dSopenharmony_ci return USEARCH_DONE; 4702e5b6d6dSopenharmony_ci } 4712e5b6d6dSopenharmony_ci 4722e5b6d6dSopenharmony_ci return m_search_->matchedIndex; 4732e5b6d6dSopenharmony_ci#endif 4742e5b6d6dSopenharmony_ci } 4752e5b6d6dSopenharmony_ci 4762e5b6d6dSopenharmony_ci return m_search_->matchedIndex; 4772e5b6d6dSopenharmony_ci } 4782e5b6d6dSopenharmony_ci return USEARCH_DONE; 4792e5b6d6dSopenharmony_ci} 4802e5b6d6dSopenharmony_ci 4812e5b6d6dSopenharmony_ciU_NAMESPACE_END 4822e5b6d6dSopenharmony_ci 4832e5b6d6dSopenharmony_ci#endif /* #if !UCONFIG_NO_COLLATION */ 484