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