package be.nikiroo.utils.streams; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; /** * This {@link InputStream} will replace some of its content by replacing it * with something else. * * @author niki */ public class ReplaceInputStream extends BufferedInputStream { private byte[] from; private byte[] to; private byte[] source; private int spos; private int slen; /** * Create a {@link ReplaceInputStream} that will replace from with * to. * * @param in * the under-laying {@link InputStream} * @param from * the {@link String} to replace * @param to * the {@link String} to replace with */ public ReplaceInputStream(InputStream in, String from, String to) { this(in, bytes(from), bytes(to)); } /** * Create a {@link ReplaceInputStream} that will replace from with * to. * * @param in * the under-laying {@link InputStream} * @param from * the value to replace * @param to * the value to replace with */ public ReplaceInputStream(InputStream in, byte[] from, byte[] to) { super(in); this.from = from; this.to = to; source = new byte[4096]; spos = 0; slen = 0; } @Override protected int read(InputStream in, byte[] buffer) throws IOException { if (buffer.length < to.length || source.length < to.length * 2) { throw new IOException( "An underlaying buffer is too small for this replace value"); } if (spos >= slen) { spos = 0; slen = in.read(source); } // Note: very simple, not efficient implementation, sorry. int count = 0; while (spos < slen && count < buffer.length - to.length) { if (from.length > 0 && startsWith(from, source, spos, slen)) { System.arraycopy(to, 0, buffer, spos, to.length); count += to.length; spos += from.length; } else { buffer[count++] = source[spos++]; } } return count; } /** * Return the bytes array representation of the given {@link String} in * UTF-8. * * @param str * the string to transform into bytes * @return the content in bytes */ static private byte[] bytes(String str) { try { return str.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { // All conforming JVM must support UTF-8 e.printStackTrace(); return null; } } }