X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fstreams%2FReplaceInputStream.java;h=9f733504117c314768603669b73cde0f7aa2ab40;hb=4a464a06db3158e31c64aa798ddce9df1ec7f5f5;hp=eea3a1ab9b74b42158d5b40e565b59c839cb690a;hpb=627f866e6cd474bd7494750dc3846c5ad898f2ec;p=nikiroo-utils.git diff --git a/src/be/nikiroo/utils/streams/ReplaceInputStream.java b/src/be/nikiroo/utils/streams/ReplaceInputStream.java index eea3a1a..9f73350 100644 --- a/src/be/nikiroo/utils/streams/ReplaceInputStream.java +++ b/src/be/nikiroo/utils/streams/ReplaceInputStream.java @@ -3,6 +3,8 @@ package be.nikiroo.utils.streams; import java.io.IOException; import java.io.InputStream; +import be.nikiroo.utils.StringUtils; + /** * This {@link InputStream} will change some of its content by replacing it with * something else. @@ -10,8 +12,18 @@ import java.io.InputStream; * @author niki */ public class ReplaceInputStream extends BufferedInputStream { + /** + * The minimum size of the internal buffer (could be more if at least one of + * the 'FROM' bytes arrays is > 2048 bytes — in that case the + * buffer will be twice the largest size of the 'FROM' bytes arrays). + *

+ * This is a different buffer than the one from the inherited class. + */ + static private final int MIN_BUFFER_SIZE = 4096; + private byte[][] froms; private byte[][] tos; + private int maxFromSize; private int maxToSize; private byte[] source; @@ -30,7 +42,7 @@ public class ReplaceInputStream extends BufferedInputStream { * the {@link String} to replace with */ public ReplaceInputStream(InputStream in, String from, String to) { - this(in, StreamUtils.bytes(from), StreamUtils.bytes(to)); + this(in, StringUtils.getBytes(from), StringUtils.getBytes(to)); } /** @@ -63,7 +75,7 @@ public class ReplaceInputStream extends BufferedInputStream { * the values to replace with */ public ReplaceInputStream(InputStream in, String[] froms, String[] tos) { - this(in, StreamUtils.bytes(froms), StreamUtils.bytes(tos)); + this(in, StreamUtils.getBytes(froms), StreamUtils.getBytes(tos)); } /** @@ -91,39 +103,49 @@ public class ReplaceInputStream extends BufferedInputStream { this.froms = froms; this.tos = tos; + maxFromSize = 0; + for (int i = 0; i < froms.length; i++) { + maxFromSize = Math.max(maxFromSize, froms[i].length); + } + + maxToSize = 0; for (int i = 0; i < tos.length; i++) { maxToSize = Math.max(maxToSize, tos[i].length); } - source = new byte[4096]; + // We need at least maxFromSize so we can iterate and replace + source = new byte[Math.max(2 * maxFromSize, MIN_BUFFER_SIZE)]; spos = 0; slen = 0; } @Override - protected int read(InputStream in, byte[] buffer) throws IOException { - if (buffer.length < maxToSize || source.length < maxToSize * 2) { + protected int read(InputStream in, byte[] buffer, int off, int len) + throws IOException { + if (len < maxToSize || source.length < maxToSize * 2) { throw new IOException( "An underlaying buffer is too small for these replace values"); } - if (spos >= slen) { + // We need at least one byte of data to process + if (available() < Math.max(maxFromSize, 1) && !eof) { spos = 0; slen = in.read(source); } - // Note: very simple, not efficient implementation, sorry. + // Note: very simple, not efficient implementation; sorry. int count = 0; - while (spos < slen && count < buffer.length - maxToSize) { + while (spos < slen && count < len - maxToSize) { boolean replaced = false; for (int i = 0; i < froms.length; i++) { if (froms[i] != null && froms[i].length > 0 && StreamUtils.startsWith(froms[i], source, spos, slen)) { if (tos[i] != null && tos[i].length > 0) { - System.arraycopy(tos[i], 0, buffer, spos, tos[i].length); + System.arraycopy(tos[i], 0, buffer, off + count, + tos[i].length); count += tos[i].length; } - + spos += froms[i].length; replaced = true; break; @@ -131,7 +153,7 @@ public class ReplaceInputStream extends BufferedInputStream { } if (!replaced) { - buffer[count++] = source[spos++]; + buffer[off + count++] = source[spos++]; } }