X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fstreams%2FReplaceInputStream.java;h=eea3a1ab9b74b42158d5b40e565b59c839cb690a;hb=2e465ed3dc72efcdf96e419b39d6119c0cc41c6c;hp=f5138eefeafc327dbd865e3b89713843c027aa0a;hpb=c8ce09c4dc57142f94afcdc290dd79c4bddf7820;p=nikiroo-utils.git diff --git a/src/be/nikiroo/utils/streams/ReplaceInputStream.java b/src/be/nikiroo/utils/streams/ReplaceInputStream.java index f5138ee..0860f78 100644 --- a/src/be/nikiroo/utils/streams/ReplaceInputStream.java +++ b/src/be/nikiroo/utils/streams/ReplaceInputStream.java @@ -2,6 +2,10 @@ package be.nikiroo.utils.streams; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import be.nikiroo.utils.StringUtils; /** * This {@link InputStream} will change some of its content by replacing it with @@ -10,12 +14,19 @@ import java.io.InputStream; * @author niki */ public class ReplaceInputStream extends BufferedInputStream { - private byte[] from; - private byte[] to; + /** + * 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[] source; - private int spos; - private int slen; + private byte[][] froms; + private byte[][] tos; + private int bufferSize; + private int maxFromSize; /** * Create a {@link ReplaceInputStream} that will replace from with @@ -29,7 +40,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)); } /** @@ -44,40 +55,163 @@ public class ReplaceInputStream extends BufferedInputStream { * the value to replace with */ public ReplaceInputStream(InputStream in, byte[] from, byte[] to) { + this(in, new byte[][] { from }, new byte[][] { to }); + } + + /** + * Create a {@link ReplaceInputStream} that will replace all froms + * with tos. + *
+ * Note that they will be replaced in order, and that for each from + * a to must correspond. + * + * @param in + * the under-laying {@link InputStream} + * @param froms + * the values to replace + * @param tos + * the values to replace with + */ + public ReplaceInputStream(InputStream in, String[] froms, String[] tos) { + this(in, StreamUtils.getBytes(froms), StreamUtils.getBytes(tos)); + } + + /** + * Create a {@link ReplaceInputStream} that will replace all froms + * with tos. + *
+ * Note that they will be replaced in order, and that for each from
+ * a to must correspond.
+ *
+ * @param in
+ * the under-laying {@link InputStream}
+ * @param froms
+ * the values to replace
+ * @param tos
+ * the values to replace with
+ */
+ public ReplaceInputStream(InputStream in, byte[][] froms, byte[][] tos) {
super(in);
- this.from = from;
- this.to = to;
- source = new byte[4096];
- spos = 0;
- slen = 0;
+ if (froms.length != tos.length) {
+ throw new IllegalArgumentException(
+ "For replacing, each FROM must have a corresponding TO");
+ }
+
+ this.froms = froms;
+ this.tos = tos;
+
+ maxFromSize = 0;
+ for (int i = 0; i < froms.length; i++) {
+ maxFromSize = Math.max(maxFromSize, froms[i].length);
+ }
+
+ int maxToSize = 0;
+ for (int i = 0; i < tos.length; i++) {
+ maxToSize = Math.max(maxToSize, tos[i].length);
+ }
+
+ // We need at least maxFromSize so we can iterate and replace
+ bufferSize = Math.max(4 * Math.max(maxToSize, maxFromSize),
+ MIN_BUFFER_SIZE);
+ }
+
+ @Override
+ protected boolean preRead() throws IOException {
+ boolean rep = super.preRead();
+ start = stop;
+ return rep;
}
@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");
+ buffer = null; // do not use the buffer.
+
+ byte[] newBuffer = new byte[bufferSize];
+ int read = 0;
+ while (read < bufferSize / 2) {
+ int thisTime = in.read(newBuffer, read, bufferSize / 2 - read);
+ if (thisTime <= 0) {
+ break;
+ }
+ read += thisTime;
+ }
+
+ List