]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/search.cpp
ICU-64243.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / search.cpp
index c190e94b103631cb41953f29f7611f5d560b93d6..f944b68455ab7b24e1654e80c91f4083601990d0 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 2001 IBM and others. All rights reserved.
+*   Copyright (C) 2001-2008,2010 IBM and others. All rights reserved.
 **********************************************************************
 *   Date        Name        Description
 *  03/22/2000   helena      Creation.
@@ -9,7 +11,7 @@
 
 #include "unicode/utypes.h"
 
-#if !UCONFIG_NO_COLLATION
+#if !UCONFIG_NO_COLLATION && !UCONFIG_NO_BREAK_ITERATION
 
 #include "unicode/brkiter.h"
 #include "unicode/schriter.h"
@@ -29,6 +31,7 @@ SearchIterator::SearchIterator(const SearchIterator &other)
     m_search_->breakIter        = other.m_search_->breakIter;
     m_search_->isCanonicalMatch = other.m_search_->isCanonicalMatch;
     m_search_->isOverlap        = other.m_search_->isOverlap;
+    m_search_->elementComparisonType = other.m_search_->elementComparisonType;
     m_search_->matchedIndex     = other.m_search_->matchedIndex;
     m_search_->matchedLength    = other.m_search_->matchedLength;
     m_search_->text             = other.m_search_->text;
@@ -57,6 +60,13 @@ void SearchIterator::setAttribute(USearchAttribute       attribute,
         case USEARCH_CANONICAL_MATCH :
             m_search_->isCanonicalMatch = (value == USEARCH_ON ? TRUE : FALSE);
             break;
+        case USEARCH_ELEMENT_COMPARISON :
+            if (value == USEARCH_PATTERN_BASE_WEIGHT_IS_WILDCARD || value == USEARCH_ANY_BASE_WEIGHT_IS_WILDCARD) {
+                m_search_->elementComparisonType = (int16_t)value;
+            } else {
+                m_search_->elementComparisonType = 0;
+            }
+            break;
         default:
             status = U_ILLEGAL_ARGUMENT_ERROR;
         }
@@ -75,6 +85,15 @@ USearchAttributeValue SearchIterator::getAttribute(
     case USEARCH_CANONICAL_MATCH :
         return (m_search_->isCanonicalMatch == TRUE ? USEARCH_ON : 
                                                                 USEARCH_OFF);
+    case USEARCH_ELEMENT_COMPARISON :
+        {
+            int16_t value = m_search_->elementComparisonType;
+            if (value == USEARCH_PATTERN_BASE_WEIGHT_IS_WILDCARD || value == USEARCH_ANY_BASE_WEIGHT_IS_WILDCARD) {
+                return (USearchAttributeValue)value;
+            } else {
+                return USEARCH_STANDARD_ELEMENT_COMPARISON;
+            }
+        }
     default :
         return USEARCH_DEFAULT;
     }
@@ -106,9 +125,21 @@ void SearchIterator::setBreakIterator(BreakIterator *breakiter,
                                       UErrorCode &status)
 {
     if (U_SUCCESS(status)) {
+#if 0
         m_search_->breakIter = NULL;
         // the c++ breakiterator may not make use of ubreakiterator.
         // so we'll have to keep track of it ourselves.
+#else
+        // Well, gee... the Constructors that take a BreakIterator
+        // all cast the BreakIterator to a UBreakIterator and
+        // pass it to the corresponding usearch_openFromXXX
+        // routine, so there's no reason not to do this.
+        //
+        // Besides, a UBreakIterator is a BreakIterator, so
+        // any subclass of BreakIterator should work fine here...
+        m_search_->breakIter = (UBreakIterator *) breakiter;
+#endif
+        
         m_breakiterator_ = breakiter;
     }
 }
@@ -155,6 +186,7 @@ UBool SearchIterator::operator==(const SearchIterator &that) const
     return (m_breakiterator_            == that.m_breakiterator_ &&
             m_search_->isCanonicalMatch == that.m_search_->isCanonicalMatch &&
             m_search_->isOverlap        == that.m_search_->isOverlap &&
+            m_search_->elementComparisonType == that.m_search_->elementComparisonType &&
             m_search_->matchedIndex     == that.m_search_->matchedIndex &&
             m_search_->matchedLength    == that.m_search_->matchedLength &&
             m_search_->textLength       == that.m_search_->textLength &&
@@ -283,10 +315,16 @@ int32_t SearchIterator::previous(UErrorCode &status)
         }
 
         if (matchindex != USEARCH_DONE) {
+            if (m_search_->isOverlap) {
+                matchindex += m_search_->matchedLength - 2;
+            }
+
             return handlePrev(matchindex, status); 
         }
+
         return handlePrev(offset, status);
     }
+
     return USEARCH_DONE;
 }
 
@@ -297,6 +335,7 @@ void SearchIterator::reset()
     setOffset(0, status);
     m_search_->isOverlap          = FALSE;
     m_search_->isCanonicalMatch   = FALSE;
+    m_search_->elementComparisonType = 0;
     m_search_->isForwardSearching = TRUE;
     m_search_->reset              = TRUE;
 }
@@ -309,12 +348,14 @@ SearchIterator::SearchIterator()
     m_search_->breakIter          = NULL;
     m_search_->isOverlap          = FALSE;
     m_search_->isCanonicalMatch   = FALSE;
+    m_search_->elementComparisonType = 0;
     m_search_->isForwardSearching = TRUE;
     m_search_->reset              = TRUE;
     m_search_->matchedIndex       = USEARCH_DONE;
     m_search_->matchedLength      = 0;
     m_search_->text               = NULL;
     m_search_->textLength         = 0;
+    m_breakiterator_              = NULL;
 }
 
 SearchIterator::SearchIterator(const UnicodeString &text, 
@@ -326,6 +367,7 @@ SearchIterator::SearchIterator(const UnicodeString &text,
     m_search_->breakIter          = NULL;
     m_search_->isOverlap          = FALSE;
     m_search_->isCanonicalMatch   = FALSE;
+    m_search_->elementComparisonType = 0;
     m_search_->isForwardSearching = TRUE;
     m_search_->reset              = TRUE;
     m_search_->matchedIndex       = USEARCH_DONE;
@@ -342,6 +384,7 @@ SearchIterator::SearchIterator(CharacterIterator &text,
     m_search_->breakIter          = NULL;
     m_search_->isOverlap          = FALSE;
     m_search_->isCanonicalMatch   = FALSE;
+    m_search_->elementComparisonType = 0;
     m_search_->isForwardSearching = TRUE;
     m_search_->reset              = TRUE;
     m_search_->matchedIndex       = USEARCH_DONE;
@@ -362,6 +405,7 @@ SearchIterator & SearchIterator::operator=(const SearchIterator &that)
         m_search_->breakIter        = that.m_search_->breakIter;
         m_search_->isCanonicalMatch = that.m_search_->isCanonicalMatch;
         m_search_->isOverlap        = that.m_search_->isOverlap;
+        m_search_->elementComparisonType = that.m_search_->elementComparisonType;
         m_search_->matchedIndex     = that.m_search_->matchedIndex;
         m_search_->matchedLength    = that.m_search_->matchedLength;
         m_search_->text             = that.m_search_->text;