]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/search.cpp
ICU-57131.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / search.cpp
index fca18fe77d32ddf67bf707a80f15836b536cc853..5d2aa139415afec0057b5804e6b0066803e9fe50 100644 (file)
@@ -1,6 +1,6 @@
 /*
 **********************************************************************
-*   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 +9,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 +29,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 +58,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 +83,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 +123,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 +184,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 &&
@@ -235,14 +265,14 @@ int32_t SearchIterator::next(UErrorCode &status)
         }
 
         if (matchlength > 0) {
-                       // if matchlength is 0 we are at the start of the iteration
-                       if (m_search_->isOverlap) {
-                               offset ++;
-                       }
-                       else {
-                               offset += matchlength;
-                       }
-               }
+            // if matchlength is 0 we are at the start of the iteration
+            if (m_search_->isOverlap) {
+                offset ++;
+            }
+            else {
+                offset += matchlength;
+            }
+        }
         return handleNext(offset, status);
     }
     return USEARCH_DONE;
@@ -283,10 +313,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 +333,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 +346,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 +365,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 +382,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 +403,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;