initial checkin
[org.ibex.nanogoat.git] / src / gnu / regexp / REFilterReader.java
1 /*
2  *  gnu/regexp/REFilterReader.java
3  *  Copyright (C) 2001 Lee Sau Dan
4  *  Based on gnu.regexp.REFilterInputStream by Wes Biggs
5  *
6  *  This library is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU Lesser General Public License as published
8  *  by the Free Software Foundation; either version 2.1 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 package gnu.regexp;
22 import java.io.FilterReader;
23 import java.io.Reader;
24
25 /**
26  * Replaces instances of a given RE with replacement text. 
27  *
28  * @author <A HREF="http://www.csis.hku.hk/~sdlee/">Lee Sau Dan</A>
29  * @since gnu.regexp 1.1.0
30  */
31
32 public class REFilterReader extends FilterReader {
33
34   private RE expr;
35   private String replace;
36   private String buffer;
37   private int bufpos;
38   private int offset;
39   private CharIndexedReader stream;
40
41   /**
42    * Creates an REFilterReader.  When reading from this stream,
43    * occurrences of patterns matching the supplied regular expression
44    * will be replaced with the supplied replacement text (the
45    * metacharacters $0 through $9 may be used to refer to the full
46    * match or subexpression matches.
47    *
48    * @param stream The Reader to be filtered.
49    * @param expr The regular expression to search for.
50    * @param replace The text pattern to replace matches with.  
51    */
52   public REFilterReader(Reader stream, RE expr, String replace) {
53     super(stream);
54     this.stream = new CharIndexedReader(stream,0);
55     this.expr = expr;
56     this.replace = replace;
57   }
58
59   /**
60    * Reads the next character from the stream per the general contract of
61    * Reader.read().  Returns -1 on error or end of stream.
62    */
63   public int read() {
64     // If we have buffered replace data, use it.
65     if ((buffer != null) && (bufpos < buffer.length())) {
66       return (int) buffer.charAt(bufpos++);
67     }
68
69     // check if input is at a valid position
70     if (!stream.isValid()) return -1;
71
72     REMatch mymatch = new REMatch(expr.getNumSubs(),offset,0);
73     if (expr.match(stream,mymatch)) {
74       mymatch.end[0] = mymatch.index;
75       mymatch.finish(stream);
76       stream.move(mymatch.toString().length());
77       offset += mymatch.toString().length();
78       buffer = mymatch.substituteInto(replace);
79       bufpos = 1;
80
81       if (buffer.length() > 0) {
82           return buffer.charAt(0);
83       }
84     }
85     char ch = stream.charAt(0);
86     if (ch == CharIndexed.OUT_OF_BOUNDS) return -1;
87     stream.move(1);
88     offset++;
89     return ch;
90   }
91
92   /** 
93    * Returns false.  REFilterReader does not support mark() and
94    * reset() methods. 
95    */
96   public boolean markSupported() {
97     return false;
98   }
99
100   /** Reads from the stream into the provided array. */
101   public int read(char[] b, int off, int len) {
102     int i;
103     int ok = 0;
104     while (len-- > 0) {
105       i = read();
106       if (i == -1) return (ok == 0) ? -1 : ok;
107       b[off++] = (char) i;
108       ok++;
109     }
110     return ok;
111   }
112
113   /** Reads from the stream into the provided array. */
114   public int read(char[] b) {
115     return read(b,0,b.length);
116   }
117 }