12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */
22ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/*
32ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *******************************************************************************
42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Copyright (C) 1996-2015, International Business Machines Corporation and    *
52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * others. All Rights Reserved.                                                *
62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *******************************************************************************
72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */
82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.text;
102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.CharacterIterator;
122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/**
142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tt>SearchIterator</tt> is an abstract base class that provides
152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * methods to search for a pattern within a text string. Instances of
162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tt>SearchIterator</tt> maintain a current position and scan over the
172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * target text, returning the indices the pattern is matched and the length
182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of each match.
192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tt>SearchIterator</tt> defines a protocol for text searching.
212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Subclasses provide concrete implementations of various search algorithms.
222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, <tt>StringSearch</tt> implements language-sensitive pattern
232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * matching based on the comparison rules defined in a
242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tt>RuleBasedCollator</tt> object.
252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Other options for searching include using a BreakIterator to restrict
272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the points at which matches are detected.
282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tt>SearchIterator</tt> provides an API that is similar to that of
302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * other text iteration classes such as <tt>BreakIterator</tt>. Using
312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * this class, it is easy to scan through text looking for all occurrences of
322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * a given pattern. The following example uses a <tt>StringSearch</tt>
332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * object to find all instances of "fox" in the target string. Any other
342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * subclass of <tt>SearchIterator</tt> can be used in an identical
352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * manner.
362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre><code>
372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * String target = "The quick brown fox jumped over the lazy fox";
382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * String pattern = "fox";
392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * SearchIterator iter = new StringSearch(pattern, target);
402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * for (int pos = iter.first(); pos != SearchIterator.DONE;
412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         pos = iter.next()) {
422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     System.out.println("Found match at " + pos +
432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *             ", length is " + iter.getMatchLength());
442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * }
452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </code></pre>
462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *
472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @author Laura Werner, synwee
482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see BreakIterator
492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see RuleBasedCollator
502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */
512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic abstract class SearchIterator
522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller{
532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The BreakIterator to define the boundaries of a logical match.
552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This value can be a null.
562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * See class documentation for more information.
572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setBreakIterator(BreakIterator)
582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getBreakIterator
592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see BreakIterator
602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected BreakIterator breakIterator;
622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Target text for searching.
652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setTarget(CharacterIterator)
662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getTarget
672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected CharacterIterator targetText;
692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Length of the most current match in target text.
712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Value 0 is the default value.
722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setMatchLength
732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getMatchLength
742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected int matchLength;
762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Java port of ICU4C struct USearch (usrchimp.h)
792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Note:
812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *  ICU4J already exposed some protected members such as
832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * targetText, breakIterator and matchedLength as a part of stable
842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * APIs. In ICU4C, they are exposed through USearch struct,
852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * although USearch struct itself is internal API.
862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *  This class was created for making ICU4J code parallel to
882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * ICU4C implementation. ICU4J implementation access member
892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * fields like C struct (e.g. search_.isOverlap_) mostly, except
902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * fields already exposed as protected member (e.g. search_.text()).
912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    final class Search {
942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        CharacterIterator text() {
962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return SearchIterator.this.targetText;
972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        void setTarget(CharacterIterator text) {
1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            SearchIterator.this.targetText = text;
1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /** Flag to indicate if overlapping search is to be done.
1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            E.g. looking for "aa" in "aaa" will yield matches at offset 0 and 1. */
1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        boolean isOverlap_;
1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        boolean isCanonicalMatch_;
1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ElementComparisonType elementComparisonType_;
1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BreakIterator internalBreakIter_;
1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BreakIterator breakIter() {
1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return SearchIterator.this.breakIterator;
1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        void setBreakIter(BreakIterator breakIter) {
1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            SearchIterator.this.breakIterator = breakIter;
1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int matchedIndex_;
1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int matchedLength() {
1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return SearchIterator.this.matchLength;
1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        void setMatchedLength(int matchedLength) {
1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            SearchIterator.this.matchLength = matchedLength;
1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /** Flag indicates if we are doing a forwards search */
1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        boolean isForwardSearching_;
1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /** Flag indicates if we are at the start of a string search.
1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            This indicates that we are in forward search and at the start of m_text. */
1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        boolean reset_;
1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // Convenient methods for accessing begin/end index of the
1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // target text. These are ICU4J only and are not data fields.
1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int beginIndex() {
1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (targetText == null) {
1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return 0;
1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return targetText.getBeginIndex();
1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int endIndex() {
1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (targetText == null) {
1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return 0;
1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return targetText.getEndIndex();
1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    Search search_ = new Search();
1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // public data members -------------------------------------------------
1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * DONE is returned by previous() and next() after all valid matches have
1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * been returned, and by first() and last() if there are no matches at all.
1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #previous
1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #next
1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final int DONE = -1;
1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // public methods -----------------------------------------------------
1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // public setters -----------------------------------------------------
1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>
1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Sets the position in the target text at which the next search will start.
1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This method clears any previous match.
1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * </p>
1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param position position from which to start the next search
1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @exception IndexOutOfBoundsException thrown if argument position is out
1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            of the target text range.
1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getIndex
1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public void setIndex(int position) {
1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (position < search_.beginIndex()
1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            || position > search_.endIndex()) {
1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IndexOutOfBoundsException(
1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                "setIndex(int) expected position to be between " +
1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                search_.beginIndex() + " and " + search_.endIndex());
1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.reset_ = false;
1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.setMatchedLength(0);
1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.matchedIndex_ = DONE;
1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Determines whether overlapping matches are returned. See the class
1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * documentation for more information about overlapping matches.
1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>
1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The default setting of this property is false
1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param allowOverlap flag indicator if overlapping matches are allowed
2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #isOverlapping
2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public void setOverlapping(boolean allowOverlap) {
2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.isOverlap_ = allowOverlap;
2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Set the BreakIterator that will be used to restrict the points
2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * at which matches are detected.
2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param breakiter A BreakIterator that will be used to restrict the
2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                points at which matches are detected. If a match is
2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                found, but the match's start or end index is not a
2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                boundary as determined by the {@link BreakIterator},
2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                the match will be rejected and another will be searched
2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                for. If this parameter is <tt>null</tt>, no break
2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                detection is attempted.
2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see BreakIterator
2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public void setBreakIterator(BreakIterator breakiter) {
2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.setBreakIter(breakiter);
2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (search_.breakIter() != null) {
2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // Create a clone of CharacterItearator, so it won't
2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // affect the position currently held by search_.text()
2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (search_.text() != null) {
2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                search_.breakIter().setText((CharacterIterator)search_.text().clone());
2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Set the target text to be searched. Text iteration will then begin at
2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the start of the text string. This method is useful if you want to
2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * reuse an iterator to search within a different body of text.
2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param text new text iterator to look for match,
2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @exception IllegalArgumentException thrown when text is null or has
2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *               0 length
2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getTarget
2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public void setTarget(CharacterIterator text)
2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    {
2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (text == null || text.getEndIndex() == text.getIndex()) {
2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Illegal null or empty text");
2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        text.setIndex(text.getBeginIndex());
2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.setTarget(text);
2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.matchedIndex_ = DONE;
2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.setMatchedLength(0);
2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.reset_ = true;
2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.isForwardSearching_ = true;
2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (search_.breakIter() != null) {
2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // Create a clone of CharacterItearator, so it won't
2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // affect the position currently held by search_.text()
2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            search_.breakIter().setText((CharacterIterator)text.clone());
2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (search_.internalBreakIter_ != null) {
2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            search_.internalBreakIter_.setText((CharacterIterator)text.clone());
2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    //TODO: We may add APIs below to match ICU4C APIs
2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // setCanonicalMatch
2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // public getters ----------------------------------------------------
2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * Returns the index to the match in the text string that was searched.
2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * This call returns a valid result only after a successful call to
2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * Just after construction, or after a searching method returns
2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * {@link #DONE}, this method will return {@link #DONE}.
2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * <p>
2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * Use {@link #getMatchLength} to get the matched string length.
2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    *
2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * @return index of a substring within the text string that is being
2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    *         searched.
2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * @see #first
2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * @see #next
2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * @see #previous
2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * @see #last
2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    */
2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public int getMatchStart() {
2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return search_.matchedIndex_;
2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Return the current index in the text being searched.
2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If the iteration has gone past the end of the text
2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * (or past the beginning for a backwards search), {@link #DONE}
2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * is returned.
2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return current index in the text being searched.
2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public abstract int getIndex();
2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the length of text in the string which matches the search
2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * pattern. This call returns a valid result only after a successful call
3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * to {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Just after construction, or after a searching method returns
3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@link #DONE}, this method will return 0.
3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The length of the match in the target text, or 0 if there
3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *         is no match currently.
3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #first
3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #next
3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #previous
3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #last
3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public int getMatchLength() {
3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return search_.matchedLength();
3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the BreakIterator that is used to restrict the indexes at which
3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * matches are detected. This will be the same object that was passed to
3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the constructor or to {@link #setBreakIterator}.
3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If the {@link BreakIterator} has not been set, <tt>null</tt> will be returned.
3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * See {@link #setBreakIterator} for more information.
3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the BreakIterator set to restrict logic matches
3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setBreakIterator
3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see BreakIterator
3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public BreakIterator getBreakIterator() {
3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return search_.breakIter();
3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Return the string text to be searched.
3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return text string to be searched.
3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public CharacterIterator getTarget() {
3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return search_.text();
3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the text that was matched by the most recent call to
3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If the iterator is not pointing at a valid match (e.g. just after
3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * construction or after {@link #DONE} has been returned,
3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * returns an empty string.
3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return  the substring in the target test of the most recent match,
3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *          or null if there is no match currently.
3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #first
3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #next
3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #previous
3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #last
3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String getMatchedText() {
3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (search_.matchedLength() > 0) {
3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            int limit = search_.matchedIndex_ + search_.matchedLength();
3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            StringBuilder result = new StringBuilder(search_.matchedLength());
3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            CharacterIterator it = search_.text();
3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            it.setIndex(search_.matchedIndex_);
3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            while (it.getIndex() < limit) {
3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result.append(it.current());
3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                it.next();
3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            it.setIndex(search_.matchedIndex_);
3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return result.toString();
3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return null;
3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // miscellaneous public methods -----------------------------------------
3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the index of the next point at which the text matches the
3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * search pattern, starting from the current position
3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The iterator is adjusted so that its current index (as returned by
3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@link #getIndex}) is the match position if one was found.
3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If a match is not found, {@link #DONE} will be returned and
3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the iterator will be adjusted to a position after the end of the text
3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * string.
3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The index of the next match after the current position,
3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *          or {@link #DONE} if there are no more matches.
3812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getIndex
3822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public int next() {
3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int index = getIndex(); // offset = getOffset() in ICU4C
3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int matchindex = search_.matchedIndex_;
3862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int matchlength = search_.matchedLength();
3872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.reset_ = false;
3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (search_.isForwardSearching_) {
3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            int endIdx = search_.endIndex();
3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (index == endIdx || matchindex == endIdx ||
3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    (matchindex != DONE &&
3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    matchindex + matchlength >= endIdx)) {
3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                setMatchNotFound();
3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return DONE;
3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
3962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // switching direction.
3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // if matchedIndex == DONE, it means that either a
3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // setIndex (setOffset in C) has been called or that previous ran off the text
4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // string. the iterator would have been set to offset 0 if a
4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // match is not found.
4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            search_.isForwardSearching_ = true;
4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (search_.matchedIndex_ != DONE) {
4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // there's no need to set the collation element iterator
4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // the next call to next will set the offset.
4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return matchindex;
4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
4082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (matchlength > 0) {
4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // if matchlength is 0 we are at the start of the iteration
4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (search_.isOverlap_) {
4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                index++;
4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else {
4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                index += matchlength;
4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return handleNext(index);
4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the index of the previous point at which the string text
4242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * matches the search pattern, starting at the current position.
4252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The iterator is adjusted so that its current index (as returned by
4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@link #getIndex}) is the match position if one was found.
4272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If a match is not found, {@link #DONE} will be returned and
4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the iterator will be adjusted to the index {@link #DONE}.
4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The index of the previous match before the current position,
4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *          or {@link #DONE} if there are no more matches.
4322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getIndex
4332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public int previous() {
4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int index;  // offset in ICU4C
4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (search_.reset_) {
4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            index = search_.endIndex();   // m_search_->textLength in ICU4C
4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            search_.isForwardSearching_ = false;
4392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            search_.reset_ = false;
4402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            setIndex(index);
4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
4422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            index = getIndex();
4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int matchindex = search_.matchedIndex_;
4462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (search_.isForwardSearching_) {
4472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // switching direction.
4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // if matchedIndex == DONE, it means that either a
4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // setIndex (setOffset in C) has been called or that next ran off the text
4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // string. the iterator would have been set to offset textLength if
4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // a match is not found.
4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            search_.isForwardSearching_ = false;
4532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (matchindex != DONE) {
4542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return matchindex;
4552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
4562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            int startIdx = search_.beginIndex();
4582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (index == startIdx || matchindex == startIdx) {
4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // not enough characters to match
4602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                setMatchNotFound();
4612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return DONE;
4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (matchindex != DONE) {
4662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (search_.isOverlap_) {
4672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                matchindex += search_.matchedLength() - 2;
4682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return handlePrevious(matchindex);
4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return handlePrevious(index);
4742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Return true if the overlapping property has been set.
4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * See {@link #setOverlapping(boolean)} for more information.
4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setOverlapping
4812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return true if the overlapping property has been set, false otherwise
4822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public boolean isOverlapping() {
4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return search_.isOverlap_;
4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    //TODO: We may add APIs below to match ICU4C APIs
4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // isCanonicalMatch
4892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * Resets the iteration.
4922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * Search will begin at the start of the text string if a forward
4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * iteration is initiated before a backwards iteration. Otherwise if a
4942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * backwards iteration is initiated before a forwards iteration, the
4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    * search will begin at the end of the text string.
4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    */
4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public void reset() {
4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        setMatchNotFound();
4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        setIndex(search_.beginIndex());
5002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.isOverlap_ = false;
5012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.isCanonicalMatch_ = false;
5022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.elementComparisonType_ = ElementComparisonType.STANDARD_ELEMENT_COMPARISON;
5032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.isForwardSearching_ = true;
5042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.reset_ = true;
5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
5082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the first index at which the string text matches the search
5092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * pattern. The iterator is adjusted so that its current index (as
5102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * returned by {@link #getIndex()}) is the match position if one
5112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
5122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * was found.
5132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If a match is not found, {@link #DONE} will be returned and
5142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the iterator will be adjusted to the index {@link #DONE}.
5152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The character index of the first match, or
5162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *         {@link #DONE} if there are no matches.
5172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
5182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getIndex
5192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
5202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public final int first() {
5212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int startIdx = search_.beginIndex();
5222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        setIndex(startIdx);
5232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return handleNext(startIdx);
5242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
5252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
5272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the first index equal or greater than <tt>position</tt> at which the
5282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * string text matches the search pattern. The iterator is adjusted so
5292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * that its current index (as returned by {@link #getIndex()}) is the
5302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * match position if one was found.
5312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If a match is not found, {@link #DONE} will be returned and the
5322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * iterator will be adjusted to the index {@link #DONE}.
5332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
5342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param  position where search if to start from.
5352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The character index of the first match following
5362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *         <tt>position</tt>, or {@link #DONE} if there are no matches.
5372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @throws IndexOutOfBoundsException    If position is less than or greater
5382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *      than the text range for searching.
5392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getIndex
5402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
5412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public final int following(int position) {
5422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        setIndex(position);
5432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return handleNext(position);
5442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
5452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
5472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the last index in the target text at which it matches the
5482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * search pattern. The iterator is adjusted so that its current index
5492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * (as returned by {@link #getIndex}) is the match position if one was
5502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * found.
5512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If a match is not found, {@link #DONE} will be returned and
5522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the iterator will be adjusted to the index {@link #DONE}.
5532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
5542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The index of the first match, or {@link #DONE} if
5552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *         there are no matches.
5562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getIndex
5572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
5582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public final int last() {
5592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int endIdx = search_.endIndex();
5602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        setIndex(endIdx);
5612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return handlePrevious(endIdx);
5622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
5632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
5652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the first index less than <tt>position</tt> at which the string
5662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * text matches the search pattern. The iterator is adjusted so that its
5672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * current index (as returned by {@link #getIndex}) is the match
5682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * position if one was found. If a match is not found,
5692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@link #DONE} will be returned and the iterator will be
5702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * adjusted to the index {@link #DONE}
5712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>
5722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * When the overlapping option ({@link #isOverlapping}) is off, the last index of the
5732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * result match is always less than <tt>position</tt>.
5742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * When the overlapping option is on, the result match may span across
5752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <tt>position</tt>.
5762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
5772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param  position where search is to start from.
5782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The character index of the first match preceding
5792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *         <tt>position</tt>, or {@link #DONE} if there are
5802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *         no matches.
5812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @throws IndexOutOfBoundsException If position is less than or greater than
5822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                                   the text range for searching
5832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getIndex
5842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
5852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public final int preceding(int position) {
5862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        setIndex(position);
5872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return handlePrevious(position);
5882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
5892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // protected constructor ----------------------------------------------
5912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
5932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Protected constructor for use by subclasses.
5942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Initializes the iterator with the argument target text for searching
5952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * and sets the BreakIterator.
5962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * See class documentation for more details on the use of the target text
5972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * and {@link BreakIterator}.
5982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
5992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param target The target text to be searched.
6002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param breaker A {@link BreakIterator} that is used to determine the
6012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                boundaries of a logical match. This argument can be null.
6022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @exception IllegalArgumentException thrown when argument target is null,
6032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            or of length 0
6042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see BreakIterator
6052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
6062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected SearchIterator(CharacterIterator target, BreakIterator breaker)
6072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    {
6082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (target == null
6092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            || (target.getEndIndex() - target.getBeginIndex()) == 0) {
6102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                throw new IllegalArgumentException(
6112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                   "Illegal argument target. " +
6122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                   " Argument can not be null or of length 0");
6132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.setTarget(target);
6162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.setBreakIter(breaker);
6172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (search_.breakIter() != null) {
6182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            search_.breakIter().setText((CharacterIterator)target.clone());
6192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.isOverlap_ = false;
6212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.isCanonicalMatch_ = false;
6222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.elementComparisonType_ = ElementComparisonType.STANDARD_ELEMENT_COMPARISON;
6232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.isForwardSearching_ = true;
6242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.reset_ = true;
6252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.matchedIndex_ = DONE;
6262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.setMatchedLength(0);
6272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
6282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // protected methods --------------------------------------------------
6302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
6332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Sets the length of the most recent match in the target text.
6342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Subclasses' handleNext() and handlePrevious() methods should call this
6352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * after they find a match in the target text.
6362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
6372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param length new length to set
6382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #handleNext
6392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #handlePrevious
6402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
6412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected void setMatchLength(int length)
6422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    {
6432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.setMatchedLength(length);
6442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
6452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
6472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Abstract method which subclasses override to provide the mechanism
6482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * for finding the next match in the target text. This allows different
6492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * subclasses to provide different search algorithms.
6502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>
6512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If a match is found, the implementation should return the index at
6522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * which the match starts and should call
6532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@link #setMatchLength} with the number of characters
6542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * in the target text that make up the match. If no match is found, the
6552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * method should return {@link #DONE}.
6562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
6572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param start The index in the target text at which the search
6582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *              should start.
6592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return index at which the match starts, else if match is not found
6602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *         {@link #DONE} is returned
6612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setMatchLength
6622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
6632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected abstract int handleNext(int start);
6642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
6662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Abstract method which subclasses override to provide the mechanism for
6672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * finding the previous match in the target text. This allows different
6682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * subclasses to provide different search algorithms.
6692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>
6702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * If a match is found, the implementation should return the index at
6712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * which the match starts and should call
6722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@link #setMatchLength} with the number of characters
6732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * in the target text that make up the match. If no match is found, the
6742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * method should return {@link #DONE}.
6752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
6762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param startAt   The index in the target text at which the search
6772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                  should start.
6782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return index at which the match starts, else if match is not found
6792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *         {@link #DONE} is returned
6802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setMatchLength
6812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
6822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected abstract int handlePrevious(int startAt);
6832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
6852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
68693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
687836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
6882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
6892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
6902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    //TODO: This protected method is @stable 2.0 in ICU4C
6912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected void setMatchNotFound() {
6922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.matchedIndex_ = DONE;
6932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.setMatchedLength(0);
6942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
6952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
6972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Option to control how collation elements are compared.
6982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The default value will be {@link #STANDARD_ELEMENT_COMPARISON}.
6992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>
7002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * PATTERN_BASE_WEIGHT_IS_WILDCARD supports "asymmetric search" as described in
7012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <a href="http://www.unicode.org/reports/tr10/#Asymmetric_Search">
7022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * UTS #10 Unicode Collation Algorithm</a>, while ANY_BASE_WEIGHT_IS_WILDCARD
7032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * supports a related option in which "unmarked" characters in either the
7042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * pattern or the searched text are treated as wildcards that match marked or
7052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * unmarked versions of the same character.
7062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
7072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setElementComparisonType(ElementComparisonType)
7082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getElementComparisonType()
7092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
7102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public enum ElementComparisonType {
7112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
7122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Standard collation element comparison at the specified collator strength.
7132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
7142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        STANDARD_ELEMENT_COMPARISON,
7152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
7162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Collation element comparison is modified to effectively provide behavior
7172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * between the specified strength and strength - 1.
7182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * <p>
7192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Collation elements in the pattern that have the base weight for the specified
7202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * strength are treated as "wildcards" that match an element with any other
7212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * weight at that collation level in the searched text. For example, with a
7222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * secondary-strength English collator, a plain 'e' in the pattern will match
7232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * a plain e or an e with any diacritic in the searched text, but an e with
7242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * diacritic in the pattern will only match an e with the same diacritic in
7252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * the searched text.
7262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
7272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        PATTERN_BASE_WEIGHT_IS_WILDCARD,
7282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
7302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Collation element comparison is modified to effectively provide behavior
7312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * between the specified strength and strength - 1.
7322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * <p>
7332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Collation elements in either the pattern or the searched text that have the
7342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * base weight for the specified strength are treated as "wildcards" that match
7352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * an element with any other weight at that collation level. For example, with
7362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * a secondary-strength English collator, a plain 'e' in the pattern will match
7372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * a plain e or an e with any diacritic in the searched text, but an e with
7382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * diacritic in the pattern will only match an e with the same diacritic or a
7392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * plain e in the searched text.
7402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
7412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ANY_BASE_WEIGHT_IS_WILDCARD
7422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
7432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
7452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Sets the collation element comparison type.
7462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>
7472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The default comparison type is {@link ElementComparisonType#STANDARD_ELEMENT_COMPARISON}.
7482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
7492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see ElementComparisonType
7502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #getElementComparisonType()
7512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
7522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public void setElementComparisonType(ElementComparisonType type) {
7532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        search_.elementComparisonType_ = type;
7542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
7552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
7572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the collation element comparison type.
7582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
7592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see ElementComparisonType
7602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setElementComparisonType(ElementComparisonType)
7612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
7622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public ElementComparisonType getElementComparisonType() {
7632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return search_.elementComparisonType_;
7642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
7652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller}
766