001: /*
002: *******************************************************************************
003: * Copyright (C) 1996-2004, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: */
007:
008: package com.ibm.icu.text;
009:
010: import java.text.CharacterIterator;
011:
012: /**
013: * <p>SearchIterator is an abstract base class that defines a protocol
014: * for text searching. Subclasses provide concrete implementations of
015: * various search algorithms. A concrete subclass, StringSearch, is
016: * provided that implements language-sensitive pattern matching based
017: * on the comparison rules defined in a RuleBasedCollator
018: * object. Instances of SearchIterator maintain a current position and
019: * scan over the target text, returning the indices where a match is
020: * found and the length of each match. Generally, the sequence of forward
021: * matches will be equivalent to the sequence of backward matches.One
022: * case where this statement may not hold is when non-overlapping mode
023: * is set on and there are continuous repetitive patterns in the text.
024: * Consider the case searching for pattern "aba" in the text
025: * "ababababa", setting overlapping mode off will produce forward matches
026: * at offsets 0, 4. However when a backwards search is done, the
027: * results will be at offsets 6 and 2.</p>
028: *
029: * <p>If matches searched for have boundary restrictions. BreakIterators
030: * can be used to define the valid boundaries of such a match. Once a
031: * BreakIterator is set, potential matches will be tested against the
032: * BreakIterator to determine if the boundaries are valid and that all
033: * characters in the potential match are equivalent to the pattern
034: * searched for. For example, looking for the pattern "fox" in the text
035: * "foxy fox" will produce match results at offset 0 and 5 with length 3
036: * if no BreakIterators were set. However if a WordBreakIterator is set,
037: * the only match that would be found will be at the offset 5. Since,
038: * the SearchIterator guarantees that if a BreakIterator is set, all its
039: * matches will match the given pattern exactly, a potential match that
040: * passes the BreakIterator might still not produce a valid match. For
041: * instance the pattern "e" will not be found in the string
042: * "\u00e9" (latin small letter e with acute) if a
043: * CharacterBreakIterator is used. Even though "e" is
044: * a part of the character "\u00e9" and the potential match at
045: * offset 0 length 1 passes the CharacterBreakIterator test, "\u00e9"
046: * is not equivalent to "e", hence the SearchIterator rejects the potential
047: * match. By default, the SearchIterator
048: * does not impose any boundary restriction on the matches, it will
049: * return all results that match the pattern. Illustrating with the
050: * above example, "e" will
051: * be found in the string "\u00e9" if no BreakIterator is
052: * specified.</p>
053: *
054: * <p>SearchIterator also provides a means to handle overlapping
055: * matches via the API setOverlapping(boolean). For example, if
056: * overlapping mode is set, searching for the pattern "abab" in the
057: * text "ababab" will match at positions 0 and 2, whereas if
058: * overlapping is not set, SearchIterator will only match at position
059: * 0. By default, overlapping mode is not set.</p>
060: *
061: * <p>The APIs in SearchIterator are similar to that of other text
062: * iteration classes such as BreakIterator. Using this class, it is
063: * easy to scan through text looking for all occurances of a
064: * match.</p>
065: * <p>
066: * Example of use:<br>
067: * <pre>
068: * String target = "The quick brown fox jumped over the lazy fox";
069: * String pattern = "fox";
070: * SearchIterator iter = new StringSearch(pattern, target);
071: * for (int pos = iter.first(); pos != SearchIterator.DONE;
072: * pos = iter.next()) {
073: * // println matches at offset 16 and 41 with length 3
074: * System.out.println("Found match at " + pos + ", length is "
075: * + iter.getMatchLength());
076: * }
077: * target = "ababababa";
078: * pattern = "aba";
079: * iter.setTarget(new StringCharacterIterator(pattern));
080: * iter.setOverlapping(false);
081: * System.out.println("Overlapping mode set to false");
082: * System.out.println("Forward matches of pattern " + pattern + " in text "
083: * + text + ": ");
084: * for (int pos = iter.first(); pos != SearchIterator.DONE;
085: * pos = iter.next()) {
086: * // println matches at offset 0 and 4 with length 3
087: * System.out.println("offset " + pos + ", length "
088: * + iter.getMatchLength());
089: * }
090: * System.out.println("Backward matches of pattern " + pattern + " in text "
091: * + text + ": ");
092: * for (int pos = iter.last(); pos != SearchIterator.DONE;
093: * pos = iter.previous()) {
094: * // println matches at offset 6 and 2 with length 3
095: * System.out.println("offset " + pos + ", length "
096: * + iter.getMatchLength());
097: * }
098: * System.out.println("Overlapping mode set to true");
099: * System.out.println("Index set to 2");
100: * iter.setIndex(2);
101: * iter.setOverlapping(true);
102: * System.out.println("Forward matches of pattern " + pattern + " in text "
103: * + text + ": ");
104: * for (int pos = iter.first(); pos != SearchIterator.DONE;
105: * pos = iter.next()) {
106: * // println matches at offset 2, 4 and 6 with length 3
107: * System.out.println("offset " + pos + ", length "
108: * + iter.getMatchLength());
109: * }
110: * System.out.println("Index set to 2");
111: * iter.setIndex(2);
112: * System.out.println("Backward matches of pattern " + pattern + " in text "
113: * + text + ": ");
114: * for (int pos = iter.last(); pos != SearchIterator.DONE;
115: * pos = iter.previous()) {
116: * // println matches at offset 0 with length 3
117: * System.out.println("offset " + pos + ", length "
118: * + iter.getMatchLength());
119: * }
120: * </pre>
121: * </p>
122: * @author Laura Werner, synwee
123: * @stable ICU 2.0
124: * @see BreakIterator
125: */
126: public abstract class SearchIterator {
127:
128: // public data members -------------------------------------------------
129:
130: /**
131: * DONE is returned by previous() and next() after all valid matches have
132: * been returned, and by first() and last() if there are no matches at all.
133: * @see #previous
134: * @see #next
135: * @stable ICU 2.0
136: */
137: public static final int DONE = -1;
138:
139: // public methods -----------------------------------------------------
140:
141: // public setters -----------------------------------------------------
142:
143: /**
144: * <p>
145: * Sets the position in the target text at which the next search will start.
146: * This method clears any previous match.
147: * </p>
148: * @param position position from which to start the next search
149: * @exception IndexOutOfBoundsException thrown if argument position is out
150: * of the target text range.
151: * @see #getIndex
152: * @stable ICU 2.8
153: */
154: public void setIndex(int position) {
155: if (position < targetText.getBeginIndex()
156: || position > targetText.getEndIndex()) {
157: throw new IndexOutOfBoundsException(
158: "setIndex(int) expected position to be between "
159: + targetText.getBeginIndex() + " and "
160: + targetText.getEndIndex());
161: }
162: m_setOffset_ = position;
163: m_reset_ = false;
164: matchLength = 0;
165: }
166:
167: /**
168: * <p>
169: * Determines whether overlapping matches are returned. See the class
170: * documentation for more information about overlapping matches.
171: * </p>
172: * <p>
173: * The default setting of this property is false
174: * </p>
175: * @param allowOverlap flag indicator if overlapping matches are allowed
176: * @see #isOverlapping
177: * @stable ICU 2.8
178: */
179: public void setOverlapping(boolean allowOverlap) {
180: m_isOverlap_ = allowOverlap;
181: }
182:
183: /**
184: * Set the BreakIterator that is used to restrict the points at which
185: * matches are detected.
186: * Using <tt>null</tt> as the parameter is legal; it means that break
187: * detection should not be attempted.
188: * See class documentation for more information.
189: * @param breakiter A BreakIterator that will be used to restrict the
190: * points at which matches are detected.
191: * @see #getBreakIterator
192: * @see BreakIterator
193: * @stable ICU 2.0
194: */
195: public void setBreakIterator(BreakIterator breakiter) {
196: breakIterator = breakiter;
197: if (breakIterator != null) {
198: breakIterator.setText(targetText);
199: }
200: }
201:
202: /**
203: * Set the target text to be searched. Text iteration will then begin at
204: * the start of the text string. This method is useful if you want to
205: * reuse an iterator to search within a different body of text.
206: * @param text new text iterator to look for match,
207: * @exception IllegalArgumentException thrown when text is null or has
208: * 0 length
209: * @see #getTarget
210: * @stable ICU 2.4
211: */
212: public void setTarget(CharacterIterator text) {
213: if (text == null || text.getEndIndex() == text.getIndex()) {
214: throw new IllegalArgumentException(
215: "Illegal null or empty text");
216: }
217:
218: targetText = text;
219: targetText.setIndex(targetText.getBeginIndex());
220: matchLength = 0;
221: m_reset_ = true;
222: m_isForwardSearching_ = true;
223: if (breakIterator != null) {
224: breakIterator.setText(targetText);
225: }
226: }
227:
228: // public getters ----------------------------------------------------
229:
230: /**
231: * <p>
232: * Returns the index of the most recent match in the target text.
233: * This call returns a valid result only after a successful call to
234: * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
235: * Just after construction, or after a searching method returns
236: * <tt>DONE</tt>, this method will return <tt>DONE</tt>.
237: * </p>
238: * <p>
239: * Use <tt>getMatchLength</tt> to get the length of the matched text.
240: * <tt>getMatchedText</tt> will return the subtext in the searched
241: * target text from index getMatchStart() with length getMatchLength().
242: * </p>
243: * @return index to a substring within the text string that is being
244: * searched.
245: * @see #getMatchLength
246: * @see #getMatchedText
247: * @see #first
248: * @see #next
249: * @see #previous
250: * @see #last
251: * @see #DONE
252: * @stable ICU 2.8
253: */
254: public int getMatchStart() {
255: return m_lastMatchStart_;
256: }
257:
258: /**
259: * Return the index in the target text at which the iterator is currently
260: * positioned.
261: * If the iteration has gone past the end of the target text, or past
262: * the beginning for a backwards search, {@link #DONE} is returned.
263: * @return index in the target text at which the iterator is currently
264: * positioned.
265: * @stable ICU 2.8
266: * @see #first
267: * @see #next
268: * @see #previous
269: * @see #last
270: * @see #DONE
271: */
272: public abstract int getIndex();
273:
274: /**
275: * <p>
276: * Returns the length of the most recent match in the target text.
277: * This call returns a valid result only after a successful
278: * call to {@link #first}, {@link #next}, {@link #previous}, or
279: * {@link #last}.
280: * Just after construction, or after a searching method returns
281: * <tt>DONE</tt>, this method will return 0. See getMatchStart() for
282: * more details.
283: * </p>
284: * @return The length of the most recent match in the target text, or 0 if
285: * there is no match.
286: * @see #getMatchStart
287: * @see #getMatchedText
288: * @see #first
289: * @see #next
290: * @see #previous
291: * @see #last
292: * @see #DONE
293: * @stable ICU 2.0
294: */
295: public int getMatchLength() {
296: return matchLength;
297: }
298:
299: /**
300: * Returns the BreakIterator that is used to restrict the indexes at which
301: * matches are detected. This will be the same object that was passed to
302: * the constructor or to <code>setBreakIterator</code>.
303: * If the BreakIterator has not been set, <tt>null</tt> will be returned.
304: * See setBreakIterator for more information.
305: * @return the BreakIterator set to restrict logic matches
306: * @see #setBreakIterator
307: * @see BreakIterator
308: * @stable ICU 2.0
309: */
310: public BreakIterator getBreakIterator() {
311: return breakIterator;
312: }
313:
314: /**
315: * Return the target text that is being searched.
316: * @return target text being searched.
317: * @see #setTarget
318: * @stable ICU 2.0
319: */
320: public CharacterIterator getTarget() {
321: return targetText;
322: }
323:
324: /**
325: * Returns the text that was matched by the most recent call to
326: * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
327: * If the iterator is not pointing at a valid match, for instance just
328: * after construction or after <tt>DONE</tt> has been returned, an empty
329: * String will be returned. See getMatchStart for more information
330: * @see #getMatchStart
331: * @see #getMatchLength
332: * @see #first
333: * @see #next
334: * @see #previous
335: * @see #last
336: * @see #DONE
337: * @return the substring in the target text of the most recent match
338: * @stable ICU 2.0
339: */
340: public String getMatchedText() {
341: if (matchLength > 0) {
342: int limit = m_lastMatchStart_ + matchLength;
343: StringBuffer result = new StringBuffer(matchLength);
344: result.append(targetText.current());
345: targetText.next();
346: while (targetText.getIndex() < limit) {
347: result.append(targetText.current());
348: targetText.next();
349: }
350: targetText.setIndex(m_lastMatchStart_);
351: return result.toString();
352: }
353: return null;
354: }
355:
356: // miscellaneous public methods -----------------------------------------
357:
358: /**
359: * Search <b>forwards</b> in the target text for the next valid match,
360: * starting the search from the current iterator position. The iterator is
361: * adjusted so that its current index, as returned by {@link #getIndex},
362: * is the starting position of the match if one was found. If a match is
363: * found, the index of the match is returned, otherwise <tt>DONE</tt> is
364: * returned. If overlapping mode is set, the beginning of the found match
365: * can be before the end of the current match, if any.
366: * @return The starting index of the next forward match after the current
367: * iterator position, or
368: * <tt>DONE</tt> if there are no more matches.
369: * @see #getMatchStart
370: * @see #getMatchLength
371: * @see #getMatchedText
372: * @see #following
373: * @see #preceding
374: * @see #previous
375: * @see #first
376: * @see #last
377: * @see #DONE
378: * @stable ICU 2.0
379: */
380: public int next() {
381: int start = targetText.getIndex();
382: if (m_setOffset_ != DONE) {
383: start = m_setOffset_;
384: m_setOffset_ = DONE;
385: }
386: if (m_isForwardSearching_) {
387: if (!m_reset_
388: && start + matchLength >= targetText.getEndIndex()) {
389: // not enough characters to match
390: matchLength = 0;
391: targetText.setIndex(targetText.getEndIndex());
392: m_lastMatchStart_ = DONE;
393: return DONE;
394: }
395: m_reset_ = false;
396: } else {
397: // switching direction.
398: // if matchedIndex == USEARCH_DONE, it means that either a
399: // setIndex has been called or that previous ran off the text
400: // string. the iterator would have been set to offset 0 if a
401: // match is not found.
402: m_isForwardSearching_ = true;
403: if (start != DONE) {
404: // there's no need to set the collation element iterator
405: // the next call to next will set the offset.
406: return start;
407: }
408: }
409:
410: if (start == DONE) {
411: start = targetText.getBeginIndex();
412: }
413: if (matchLength > 0) {
414: // if match length is 0 we are at the start of the iteration
415: if (m_isOverlap_) {
416: start++;
417: } else {
418: start += matchLength;
419: }
420: }
421: m_lastMatchStart_ = handleNext(start);
422: return m_lastMatchStart_;
423: }
424:
425: /**
426: * Search <b>backwards</b> in the target text for the next valid match,
427: * starting the search from the current iterator position. The iterator is
428: * adjusted so that its current index, as returned by {@link #getIndex},
429: * is the starting position of the match if one was found. If a match is
430: * found, the index is returned, otherwise <tt>DONE</tt> is returned. If
431: * overlapping mode is set, the end of the found match can be after the
432: * beginning of the previous match, if any.
433: * @return The starting index of the next backwards match after the current
434: * iterator position, or
435: * <tt>DONE</tt> if there are no more matches.
436: * @see #getMatchStart
437: * @see #getMatchLength
438: * @see #getMatchedText
439: * @see #following
440: * @see #preceding
441: * @see #next
442: * @see #first
443: * @see #last
444: * @see #DONE
445: * @stable ICU 2.0
446: */
447: public int previous() {
448: int start = targetText.getIndex();
449: if (m_setOffset_ != DONE) {
450: start = m_setOffset_;
451: m_setOffset_ = DONE;
452: }
453: if (m_reset_) {
454: m_isForwardSearching_ = false;
455: m_reset_ = false;
456: start = targetText.getEndIndex();
457: }
458:
459: if (m_isForwardSearching_ == true) {
460: // switching direction.
461: // if matchedIndex == USEARCH_DONE, it means that either a
462: // setIndex has been called or that next ran off the text
463: // string. the iterator would have been set to offset textLength if
464: // a match is not found.
465: m_isForwardSearching_ = false;
466: if (start != targetText.getEndIndex()) {
467: return start;
468: }
469: } else {
470: if (start == targetText.getBeginIndex()) {
471: // not enough characters to match
472: matchLength = 0;
473: targetText.setIndex(targetText.getBeginIndex());
474: m_lastMatchStart_ = DONE;
475: return DONE;
476: }
477: }
478:
479: m_lastMatchStart_ = handlePrevious(start);
480: return m_lastMatchStart_;
481: }
482:
483: /**
484: * Return true if the overlapping property has been set.
485: * See setOverlapping(boolean) for more information.
486: * @see #setOverlapping
487: * @return true if the overlapping property has been set, false otherwise
488: * @stable ICU 2.8
489: */
490: public boolean isOverlapping() {
491: return m_isOverlap_;
492: }
493:
494: /**
495: * <p>
496: * Resets the search iteration. All properties will be reset to their
497: * default values.
498: * </p>
499: * <p>
500: * If a forward iteration is initiated, the next search will begin at the
501: * start of the target text. Otherwise, if a backwards iteration is initiated,
502: * the next search will begin at the end of the target text.
503: * </p>
504: * @stable ICU 2.8
505: */
506: public void reset() {
507: // reset is setting the attributes that are already in string search
508: matchLength = 0;
509: setIndex(targetText.getBeginIndex());
510: m_isOverlap_ = false;
511: m_isForwardSearching_ = true;
512: m_reset_ = true;
513: m_setOffset_ = DONE;
514: }
515:
516: /**
517: * Return the index of the first <b>forward</b> match in the target text.
518: * This method sets the iteration to begin at the start of the
519: * target text and searches forward from there.
520: * @return The index of the first forward match, or <code>DONE</code>
521: * if there are no matches.
522: * @see #getMatchStart
523: * @see #getMatchLength
524: * @see #getMatchedText
525: * @see #following
526: * @see #preceding
527: * @see #next
528: * @see #previous
529: * @see #last
530: * @see #DONE
531: * @stable ICU 2.0
532: */
533: public final int first() {
534: m_isForwardSearching_ = true;
535: setIndex(targetText.getBeginIndex());
536: return next();
537: }
538:
539: /**
540: * Return the index of the first <b>forward</b> match in target text that
541: * is at or after argument <tt>position</tt>.
542: * This method sets the iteration to begin at the specified
543: * position in the the target text and searches forward from there.
544: * @return The index of the first forward match, or <code>DONE</code>
545: * if there are no matches.
546: * @see #getMatchStart
547: * @see #getMatchLength
548: * @see #getMatchedText
549: * @see #first
550: * @see #preceding
551: * @see #next
552: * @see #previous
553: * @see #last
554: * @see #DONE
555: * @stable ICU 2.0
556: */
557: public final int following(int position) {
558: m_isForwardSearching_ = true;
559: // position checked in usearch_setOffset
560: setIndex(position);
561: return next();
562: }
563:
564: /**
565: * Return the index of the first <b>backward</b> match in target text.
566: * This method sets the iteration to begin at the end of the
567: * target text and searches backwards from there.
568: * @return The starting index of the first backward match, or
569: * <code>DONE</code> if there are no matches.
570: * @see #getMatchStart
571: * @see #getMatchLength
572: * @see #getMatchedText
573: * @see #first
574: * @see #preceding
575: * @see #next
576: * @see #previous
577: * @see #following
578: * @see #DONE
579: * @stable ICU 2.0
580: */
581: public final int last() {
582: m_isForwardSearching_ = false;
583: setIndex(targetText.getEndIndex());
584: return previous();
585: }
586:
587: /**
588: * Return the index of the first <b>backwards</b> match in target
589: * text that ends at or before argument <tt>position</tt>.
590: * This method sets the iteration to begin at the argument
591: * position index of the target text and searches backwards from there.
592: * @return The starting index of the first backwards match, or
593: * <code>DONE</code>
594: * if there are no matches.
595: * @see #getMatchStart
596: * @see #getMatchLength
597: * @see #getMatchedText
598: * @see #first
599: * @see #following
600: * @see #next
601: * @see #previous
602: * @see #last
603: * @see #DONE
604: * @stable ICU 2.0
605: */
606: public final int preceding(int position) {
607: m_isForwardSearching_ = false;
608: // position checked in usearch_setOffset
609: setIndex(position);
610: return previous();
611: }
612:
613: // protected data member ----------------------------------------------
614:
615: /**
616: * The BreakIterator to define the boundaries of a logical match.
617: * This value can be a null.
618: * See class documentation for more information.
619: * @see #setBreakIterator(BreakIterator)
620: * @see #getBreakIterator
621: * @see BreakIterator
622: * @stable ICU 2.0
623: */
624: protected BreakIterator breakIterator;
625:
626: /**
627: * Target text for searching.
628: * @see #setTarget(CharacterIterator)
629: * @see #getTarget
630: * @stable ICU 2.0
631: */
632: protected CharacterIterator targetText;
633: /**
634: * Length of the most current match in target text.
635: * Value 0 is the default value.
636: * @see #setMatchLength
637: * @see #getMatchLength
638: * @stable ICU 2.0
639: */
640: protected int matchLength;
641:
642: // protected constructor ----------------------------------------------
643:
644: /**
645: * Protected constructor for use by subclasses.
646: * Initializes the iterator with the argument target text for searching
647: * and sets the BreakIterator.
648: * See class documentation for more details on the use of the target text
649: * and BreakIterator.
650: * @param target The target text to be searched.
651: * @param breaker A {@link BreakIterator} that is used to determine the
652: * boundaries of a logical match. This argument can be null.
653: * @exception IllegalArgumentException thrown when argument target is null,
654: * or of length 0
655: * @see BreakIterator
656: * @stable ICU 2.0
657: */
658: protected SearchIterator(CharacterIterator target,
659: BreakIterator breaker) {
660: if (target == null
661: || (target.getEndIndex() - target.getBeginIndex()) == 0) {
662: throw new IllegalArgumentException(
663: "Illegal argument target. "
664: + " Argument can not be null or of length 0");
665: }
666: targetText = target;
667: breakIterator = breaker;
668: if (breakIterator != null) {
669: breakIterator.setText(target);
670: }
671: matchLength = 0;
672: m_lastMatchStart_ = DONE;
673: m_isOverlap_ = false;
674: m_isForwardSearching_ = true;
675: m_reset_ = true;
676: m_setOffset_ = DONE;
677: }
678:
679: // protected methods --------------------------------------------------
680:
681: /**
682: * Sets the length of the most recent match in the target text.
683: * Subclasses' handleNext() and handlePrevious() methods should call this
684: * after they find a match in the target text.
685: * @param length new length to set
686: * @see #handleNext
687: * @see #handlePrevious
688: * @stable ICU 2.0
689: */
690: protected void setMatchLength(int length) {
691: matchLength = length;
692: }
693:
694: /**
695: * <p>
696: * Abstract method that subclasses override to provide the mechanism
697: * for finding the next <b>forwards</b> match in the target text. This
698: * allows different subclasses to provide different search algorithms.
699: * </p>
700: * <p>
701: * If a match is found, this function must call setMatchLength(int) to
702: * set the length of the result match.
703: * The iterator is adjusted so that its current index, as returned by
704: * {@link #getIndex}, is the starting position of the match if one was
705: * found. If a match is not found, <tt>DONE</tt> will be returned.
706: * </p>
707: * @param start index in the target text at which the forwards search
708: * should begin.
709: * @return the starting index of the next forwards match if found, DONE
710: * otherwise
711: * @see #setMatchLength(int)
712: * @see #handlePrevious(int)
713: * @see #DONE
714: * @stable ICU 2.0
715: */
716: protected abstract int handleNext(int start);
717:
718: /**
719: * <p>
720: * Abstract method which subclasses override to provide the mechanism
721: * for finding the next <b>backwards</b> match in the target text.
722: * This allows different
723: * subclasses to provide different search algorithms.
724: * </p>
725: * <p>
726: * If a match is found, this function must call setMatchLength(int) to
727: * set the length of the result match.
728: * The iterator is adjusted so that its current index, as returned by
729: * {@link #getIndex}, is the starting position of the match if one was
730: * found. If a match is not found, <tt>DONE</tt> will be returned.
731: * </p>
732: * @param startAt index in the target text at which the backwards search
733: * should begin.
734: * @return the starting index of the next backwards match if found,
735: * DONE otherwise
736: * @see #setMatchLength(int)
737: * @see #handleNext(int)
738: * @see #DONE
739: * @stable ICU 2.0
740: */
741: protected abstract int handlePrevious(int startAt);
742:
743: // private data members ------------------------------------------------
744:
745: /**
746: * Flag indicates if we are doing a forwards search
747: */
748: private boolean m_isForwardSearching_;
749: /**
750: * Flag to indicate if overlapping search is to be done.
751: * E.g. looking for "aa" in "aaa" will yield matches at offset 0 and 1.
752: */
753: private boolean m_isOverlap_;
754: /**
755: * Flag indicates if we are at the start of a string search.
756: * This indicates that we are in forward search and at the start of m_text.
757: */
758: private boolean m_reset_;
759: /**
760: * Data member to store user defined position in setIndex().
761: * If setIndex() is not called, this value will be DONE.
762: */
763: private int m_setOffset_;
764: /**
765: * Offset of the beginning of the last match
766: */
767: private int m_lastMatchStart_;
768: }
|