001: /*
002: * gnu/regexp/REMatchEnumeration.java
003: * Copyright (C) 1998 Wes Biggs
004: *
005: * This library is free software; you can redistribute it and/or modify
006: * it under the terms of the GNU Library General Public License as published
007: * by the Free Software Foundation; either version 2 of the License, or
008: * (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU Library General Public License for more details.
014: *
015: * You should have received a copy of the GNU Library General Public License
016: * along with this program; if not, write to the Free Software
017: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
018: */
019: package gnu.regexp;
020:
021: import java.util.Enumeration;
022: import java.util.NoSuchElementException;
023:
024: /**
025: * An REMatchEnumeration enumerates regular expression matches over a given
026: * input text. You obtain a reference to an enumeration using the
027: * <code>getMatchEnumeration()</code> methods on an instance of RE.
028: * <P>
029: * REMatchEnumeration does lazy computation; that is, it will not search for
030: * a match until it needs to. If you'd rather just get all the matches at
031: * once in a big array, use the <code>getAllMatches()</code> methods on RE.
032: * However, using an enumeration can help speed performance when the entire
033: * text does not need to be searched immediately.
034: * <P>
035: * The enumerated type is especially useful when searching on an InputStream,
036: * because the InputStream read position cannot be guaranteed after calling
037: * <code>getMatch()</code> (see the description of that method for an
038: * explanation of why). Enumeration also saves a lot of overhead required
039: * when calling <code>getMatch()</code> multiple times.
040: *
041: * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
042: */
043: public class REMatchEnumeration implements Enumeration {
044: private static final int YES = 1;
045: private static final int MAYBE = 0;
046: private static final int NO = -1;
047:
048: private int m_more;
049: private REMatch m_match;
050: private RE m_expr;
051: private CharIndexed m_input;
052: private int m_index;
053: private int m_eflags;
054: private StringBuffer m_buffer;
055:
056: // Package scope constructor is used by RE.getMatchEnumeration()
057: REMatchEnumeration(RE expr, CharIndexed input, int index, int eflags) {
058: m_more = MAYBE;
059: m_expr = expr;
060: m_input = input;
061: m_index = index;
062: m_eflags = eflags;
063: }
064:
065: /** Returns true if there are more matches in the input text. */
066: public boolean hasMoreElements() {
067: return hasMoreMatches(null);
068: }
069:
070: /** Returns true if there are more matches in the input text. */
071: public boolean hasMoreMatches() {
072: return hasMoreMatches(null);
073: }
074:
075: /** Returns true if there are more matches in the input text.
076: * Saves the text leading up to the match (or to the end of the input)
077: * in the specified buffer.
078: */
079: public boolean hasMoreMatches(StringBuffer f_buffer) {
080: if (m_more == MAYBE) {
081: m_match = m_expr.getMatchImpl(m_input, m_index, m_eflags,
082: f_buffer);
083: if (m_match != null) {
084: m_index = m_match.getEndIndex();
085: m_input.move((m_match.end[0] > 0) ? m_match.end[0] : 1);
086: m_more = YES;
087: } else
088: m_more = NO;
089: }
090: return (m_more == YES);
091: }
092:
093: /** Returns the next match in the input text. */
094: public Object nextElement() throws NoSuchElementException {
095: return nextMatch();
096: }
097:
098: /**
099: * Returns the next match in the input text. This method is provided
100: * for convenience to avoid having to explicitly cast the return value
101: * to class REMatch.
102: */
103: public REMatch nextMatch() throws NoSuchElementException {
104: if (hasMoreElements()) {
105: m_more = MAYBE;
106: return m_match;
107: }
108: throw new NoSuchElementException();
109: }
110: }
|