X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fstreams%2FReplaceOutputStream.java;h=e7e6c9f5a7c03456902e471864722af00478de48;hb=7194ac50b29064a013f177fc9cfc5aaa131a8ec4;hp=e889b76ef6b756c20ca1e2e9ecec561c45ea9a55;hpb=c8ce09c4dc57142f94afcdc290dd79c4bddf7820;p=nikiroo-utils.git diff --git a/src/be/nikiroo/utils/streams/ReplaceOutputStream.java b/src/be/nikiroo/utils/streams/ReplaceOutputStream.java index e889b76..e7e6c9f 100644 --- a/src/be/nikiroo/utils/streams/ReplaceOutputStream.java +++ b/src/be/nikiroo/utils/streams/ReplaceOutputStream.java @@ -10,8 +10,8 @@ import java.io.OutputStream; * @author niki */ public class ReplaceOutputStream extends BufferedOutputStream { - private byte[] from; - private byte[] to; + private byte[][] froms; + private byte[][] tos; /** * Create a {@link ReplaceOutputStream} that will replace from with @@ -40,23 +40,97 @@ public class ReplaceOutputStream extends BufferedOutputStream { * the value to replace with */ public ReplaceOutputStream(OutputStream out, byte[] from, byte[] to) { + this(out, new byte[][] { from }, new byte[][] { to }); + } + + /** + * Create a {@link ReplaceOutputStream} 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 out + * the under-laying {@link OutputStream} + * @param froms + * the values to replace + * @param tos + * the values to replace with + */ + public ReplaceOutputStream(OutputStream out, String[] froms, String[] tos) { + this(out, StreamUtils.bytes(froms), StreamUtils.bytes(tos)); + } + + /** + * Create a {@link ReplaceOutputStream} 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 out + * the under-laying {@link OutputStream} + * @param froms + * the values to replace + * @param tos + * the values to replace with + */ + public ReplaceOutputStream(OutputStream out, byte[][] froms, byte[][] tos) { super(out); bypassFlush = false; - this.from = from; - this.to = to; + if (froms.length != tos.length) { + throw new IllegalArgumentException( + "For replacing, each FROM must have a corresponding TO"); + } + + this.froms = froms; + this.tos = tos; } + /** + * Flush the {@link BufferedOutputStream}, write the current buffered data + * to (and optionally also flush) the under-laying stream. + *

+ * If {@link BufferedOutputStream#bypassFlush} is false, all writes to the + * under-laying stream are done in this method. + *

+ * This can be used if you want to write some data in the under-laying + * stream yourself (in that case, flush this {@link BufferedOutputStream} + * with or without flushing the under-laying stream, then you can write to + * the under-laying stream). + *

+ * But be careful! If a replacement could be done with the end o the + * currently buffered data and the start of the data to come, we obviously + * will not be able to do it. + * + * @param includingSubStream + * also flush the under-laying stream + * @throws IOException + * in case of I/O error + */ @Override - protected void flush(boolean includingSubStream) throws IOException { - // Note: very simple, not efficient implementation, sorry. + public void flush(boolean includingSubStream) throws IOException { + // Note: very simple, not efficient implementation; sorry. while (start < stop) { - if (from.length > 0 - && StreamUtils.startsWith(from, buffer, start, stop)) { - out.write(to); - bytesWritten += to.length; - start += from.length; - } else { + boolean replaced = false; + for (int i = 0; i < froms.length; i++) { + if (froms[i] != null + && froms[i].length > 0 + && StreamUtils + .startsWith(froms[i], buffer, start, stop)) { + if (tos[i] != null && tos[i].length > 0) { + out.write(tos[i]); + bytesWritten += tos[i].length; + } + + start += froms[i].length; + replaced = true; + break; + } + } + + if (!replaced) { out.write(buffer[start++]); bytesWritten++; }