Search and Replace Input Stream

9:19 PM 3 Comments

This morning, I went looking for some code that I could use for search and replace in an input stream. I couldn't find one, so I wrote one. Enjoy!


/**
*
* A search and replace input stream.
*
* @author jcummings
*
*/
public class SearchAndReplaceInputStream extends InputStream {
private InputStream is;
private char[] search;
private char[] replace;

private int len, pos, idx;
private char ch, buf[];

public SearchAndReplaceInputStream(InputStream is, String search, String replace) {
this.is = is;
this.search = search.toCharArray();
this.replace = replace.toCharArray();

len = this.search.length;
pos = 0;
idx = -1;

ch = this.search[0];
buf = new char[Math.max(this.search.length, this.replace.length)];
}

@Override
public int read() throws IOException {
if ( idx == -1 ) {
idx = 0;

int i = -1;
while ( ( i = is.read() ) != -1 && ( buf[pos] = (char)i ) == ch ) {
if ( ++pos == len ) {
break;
}

ch = search[pos];
}

if ( pos == len ) {
buf = new char[Math.max(this.search.length, this.replace.length)];
System.arraycopy(replace, 0, buf, 0, replace.length);
}

pos = 0;
ch = search[pos];
}

int toReturn = -1;
if ( idx > -1 && buf[idx] != 0 ) {
toReturn = buf[idx];
buf[idx] = 0;
if ( idx < buf.length - 1 && buf[idx + 1] != 0 ) {
idx++;
} else {
idx = -1;
buf = new char[Math.max(this.search.length, this.replace.length)];
}
}

return toReturn;
}
}

Josh Cummings

"I love to teach, as a painter loves to paint, as a singer loves to sing, as a musician loves to play" - William Lyon Phelps

3 comments:

  1. Don't we need to override read(byte[]) ?

    ReplyDelete
  2. Cijoy, if you take a look at java.io.InputStream, you'll see that read(byte[]) calls read(). Because of this, it worked for me without overriding any methods; afaik, this is the typical pattern for creating an InputStream decorator.

    ReplyDelete
  3. Looks like someone liked your code.
    https://gist.github.com/alexec/4567253

    ReplyDelete