001/* 002 * gnu/regexp/REFilterInputStream.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 */ 019 020package gnu.regexp; 021import java.io.FilterInputStream; 022import java.io.InputStream; 023 024/** 025 * Replaces instances of a given RE found within an InputStream 026 * with replacement text. The replacements are interpolated into the 027 * stream when a match is found. 028 * 029 * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A> 030 * @deprecated This class cannot properly handle all character 031 * encodings. For proper handling, use the REFilterReader 032 * class instead. 033 */ 034 035public class REFilterInputStream extends FilterInputStream { 036 037 private RE expr; 038 private String replace; 039 private String buffer; 040 private int bufpos; 041 private int offset; 042 private CharIndexedInputStream stream; 043 044 /** 045 * Creates an REFilterInputStream. When reading from this stream, 046 * occurrences of patterns matching the supplied regular expression 047 * will be replaced with the supplied replacement text (the 048 * metacharacters $0 through $9 may be used to refer to the full 049 * match or subexpression matches). 050 * 051 * @param stream The InputStream to be filtered. 052 * @param expr The regular expression to search for. 053 * @param replace The text pattern to replace matches with. 054 */ 055 public REFilterInputStream(InputStream stream, RE expr, String replace) { 056 super(stream); 057 this.stream = new CharIndexedInputStream(stream,0); 058 this.expr = expr; 059 this.replace = replace; 060 } 061 062 /** 063 * Reads the next byte from the stream per the general contract of 064 * InputStream.read(). Returns -1 on error or end of stream. 065 */ 066 public int read() { 067 // If we have buffered replace data, use it. 068 if ((buffer != null) && (bufpos < buffer.length())) { 069 return (int) buffer.charAt(bufpos++); 070 } 071 072 // check if input is at a valid position 073 if (!stream.isValid()) return -1; 074 075 REMatch mymatch = new REMatch(expr.getNumSubs(),offset,0); 076 if (expr.match(stream, mymatch)) { 077 mymatch.end[0] = mymatch.index; 078 mymatch.finish(stream); 079 stream.move(mymatch.toString().length()); 080 offset += mymatch.toString().length(); 081 buffer = mymatch.substituteInto(replace); 082 bufpos = 1; 083 084 // This is prone to infinite loops if replace string turns out empty. 085 if (buffer.length() > 0) { 086 return buffer.charAt(0); 087 } 088 } 089 char ch = stream.charAt(0); 090 if (ch == CharIndexed.OUT_OF_BOUNDS) return -1; 091 stream.move(1); 092 offset++; 093 return ch; 094 } 095 096 /** 097 * Returns false. REFilterInputStream does not support mark() and 098 * reset() methods. 099 */ 100 public boolean markSupported() { 101 return false; 102 } 103 104 /** Reads from the stream into the provided array. */ 105 public int read(byte[] b, int off, int len) { 106 int i; 107 int ok = 0; 108 while (len-- > 0) { 109 i = read(); 110 if (i == -1) return (ok == 0) ? -1 : ok; 111 b[off++] = (byte) i; 112 ok++; 113 } 114 return ok; 115 } 116 117 /** Reads from the stream into the provided array. */ 118 public int read(byte[] b) { 119 return read(b,0,b.length); 120 } 121}