X-Git-Url: http://git.nikiroo.be/?p=nikiroo-utils.git;a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fstreams%2FReplaceInputStream.java;h=0860f78c35e09b08ffe1f3326a379e1d504e5959;hp=b2187af09ce189dae52105733c10559f0db4aff0;hb=28bee1c360ac061db48395356f36ef62c2923bf1;hpb=028ff7c29a8fb07c702ffd34913a5dd22b688211 diff --git a/src/be/nikiroo/utils/streams/ReplaceInputStream.java b/src/be/nikiroo/utils/streams/ReplaceInputStream.java index b2187af..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,13 +14,19 @@ 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 maxToSize;
-
- private byte[] source;
- private int spos;
- private int slen;
+ private int bufferSize;
+ private int maxFromSize;
/**
* Create a {@link ReplaceInputStream} that will replace from with
@@ -30,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));
}
/**
@@ -63,7 +73,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,52 +101,117 @@ 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);
+ }
+
+ int maxToSize = 0;
for (int i = 0; i < tos.length; i++) {
maxToSize = Math.max(maxToSize, tos[i].length);
}
- source = new byte[4096];
- spos = 0;
- slen = 0;
+ // We need at least maxFromSize so we can iterate and replace
+ 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;
+ }
- if (spos >= slen) {
- 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