X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;ds=sidebyside;f=src%2Fbe%2Fnikiroo%2Futils%2Fstreams%2FReplaceInputStream.java;h=0860f78c35e09b08ffe1f3326a379e1d504e5959;hb=2e465ed3dc72efcdf96e419b39d6119c0cc41c6c;hp=1cc5139beae1e012053f62dece957076add4dfee;hpb=2048e74238ad24e52da623a92c31460e05ce495e;p=nikiroo-utils.git
diff --git a/src/be/nikiroo/utils/streams/ReplaceInputStream.java b/src/be/nikiroo/utils/streams/ReplaceInputStream.java
index 1cc5139..0860f78 100644
--- a/src/be/nikiroo/utils/streams/ReplaceInputStream.java
+++ b/src/be/nikiroo/utils/streams/ReplaceInputStream.java
@@ -2,6 +2,8 @@ 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;
@@ -23,12 +25,8 @@ public class ReplaceInputStream extends BufferedInputStream {
private byte[][] froms;
private byte[][] tos;
+ private int bufferSize;
private int maxFromSize;
- private int maxToSize;
-
- private byte[] source;
- private int spos;
- private int slen;
/**
* Create a {@link ReplaceInputStream} that will replace from with
@@ -108,55 +106,112 @@ public class ReplaceInputStream extends BufferedInputStream {
maxFromSize = Math.max(maxFromSize, froms[i].length);
}
- maxToSize = 0;
+ 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
- source = new byte[Math.max(2 * maxFromSize, MIN_BUFFER_SIZE)];
- spos = 0;
- slen = 0;
+ bufferSize = Math.max(4 * Math.max(maxToSize, maxFromSize),
+ MIN_BUFFER_SIZE);
}
@Override
- 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");
- }
+ protected boolean preRead() throws IOException {
+ boolean rep = super.preRead();
+ start = stop;
+ return rep;
+ }
- // We need at least one byte of data to process
- if (available() < Math.max(maxFromSize, 1) && !eof) {
- spos = 0;
- slen = in.read(source);
+ @Override
+ protected int read(InputStream in, byte[] buffer) throws IOException {
+ 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;
}
- // Note: very simple, not efficient implementation; sorry.
- int count = 0;
- 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, off + spos,
- tos[i].length);
- count += tos[i].length;
+ List bbBuffers = new ArrayList();
+ List bbOffsets = new ArrayList();
+ List bbLengths = new ArrayList();
+
+ int offset = 0;
+ for (int i = 0; i < read; i++) {
+ for (int fromIndex = 0; fromIndex < froms.length; fromIndex++) {
+ byte[] from = froms[fromIndex];
+ byte[] to = tos[fromIndex];
+
+ if (from.length > 0
+ && StreamUtils.startsWith(from, newBuffer, i, read)) {
+ if (i - offset > 0) {
+ bbBuffers.add(newBuffer);
+ bbOffsets.add(offset);
+ bbLengths.add(i - offset);
}
- spos += froms[i].length;
- replaced = true;
- break;
+ if (to.length > 0) {
+ bbBuffers.add(to);
+ bbOffsets.add(0);
+ bbLengths.add(to.length);
+ }
+
+ i += from.length;
+ offset = i;
}
}
+ }
+
+ if (offset < read) {
+ bbBuffers.add(newBuffer);
+ bbOffsets.add(offset);
+ bbLengths.add(read - offset);
+ }
- if (!replaced) {
- buffer[off + count++] = source[spos++];
+ for (int i = bbBuffers.size() - 1; i >= 0; i--) {
+ // DEBUG("pushback", bbBuffers.get(i), bbOffsets.get(i),
+ // bbLengths.get(i));
+ pushback(bbBuffers.get(i), bbOffsets.get(i), bbLengths.get(i));
+ }
+
+ return read;
+ }
+
+ // static public void DEBUG(String title, byte[] b, int off, int len) {
+ // String str = new String(b,off,len);
+ // if(str.length()>20) {
+ // str=str.substring(0,10)+" ...
+ // "+str.substring(str.length()-10,str.length());
+ // }
+ // }
+
+ @Override
+ public String toString() {
+ StringBuilder rep = new StringBuilder();
+ rep.append(getClass().getSimpleName()).append("\n");
+
+ for (int i = 0; i < froms.length; i++) {
+ byte[] from = froms[i];
+ byte[] to = tos[i];
+
+ rep.append("\t");
+ rep.append("bytes[").append(from.length).append("]");
+ if (from.length <= 20) {
+ rep.append(" (").append(new String(from)).append(")");
+ }
+ rep.append(" -> ");
+ rep.append("bytes[").append(to.length).append("]");
+ if (to.length <= 20) {
+ rep.append(" (").append(new String(to)).append(")");
}
+ rep.append("\n");
}
- return count;
+ return "[" + rep + "]";
}
}