1 package be
.nikiroo
.utils
.streams
;
3 import java
.io
.IOException
;
4 import java
.io
.OutputStream
;
6 import be
.nikiroo
.utils
.StringUtils
;
9 * This {@link OutputStream} will change some of its content by replacing it
10 * with something else.
14 public class ReplaceOutputStream
extends BufferedOutputStream
{
15 private byte[][] froms
;
19 * Create a {@link ReplaceOutputStream} that will replace <tt>from</tt> with
23 * the under-laying {@link OutputStream}
25 * the {@link String} to replace
27 * the {@link String} to replace with
29 public ReplaceOutputStream(OutputStream out
, String from
, String to
) {
30 this(out
, StringUtils
.getBytes(from
), StringUtils
.getBytes(to
));
34 * Create a {@link ReplaceOutputStream} that will replace <tt>from</tt> with
38 * the under-laying {@link OutputStream}
40 * the value to replace
42 * the value to replace with
44 public ReplaceOutputStream(OutputStream out
, byte[] from
, byte[] to
) {
45 this(out
, new byte[][] { from
}, new byte[][] { to
});
49 * Create a {@link ReplaceOutputStream} that will replace all <tt>froms</tt>
52 * Note that they will be replaced in order, and that for each <tt>from</tt>
53 * a <tt>to</tt> must correspond.
56 * the under-laying {@link OutputStream}
58 * the values to replace
60 * the values to replace with
62 public ReplaceOutputStream(OutputStream out
, String
[] froms
, String
[] tos
) {
63 this(out
, StreamUtils
.getBytes(froms
), StreamUtils
.getBytes(tos
));
67 * Create a {@link ReplaceOutputStream} that will replace all <tt>froms</tt>
70 * Note that they will be replaced in order, and that for each <tt>from</tt>
71 * a <tt>to</tt> must correspond.
74 * the under-laying {@link OutputStream}
76 * the values to replace
78 * the values to replace with
80 public ReplaceOutputStream(OutputStream out
, byte[][] froms
, byte[][] tos
) {
84 if (froms
.length
!= tos
.length
) {
85 throw new IllegalArgumentException(
86 "For replacing, each FROM must have a corresponding TO");
94 * Flush the {@link BufferedOutputStream}, write the current buffered data
95 * to (and optionally also flush) the under-laying stream.
97 * If {@link BufferedOutputStream#bypassFlush} is false, all writes to the
98 * under-laying stream are done in this method.
100 * This can be used if you want to write some data in the under-laying
101 * stream yourself (in that case, flush this {@link BufferedOutputStream}
102 * with or without flushing the under-laying stream, then you can write to
103 * the under-laying stream).
105 * <b>But be careful!</b> If a replacement could be done with the end o the
106 * currently buffered data and the start of the data to come, we obviously
107 * will not be able to do it.
109 * @param includingSubStream
110 * also flush the under-laying stream
111 * @throws IOException
112 * in case of I/O error
115 public void flush(boolean includingSubStream
) throws IOException
{
116 // Note: very simple, not efficient implementation; sorry.
117 while (start
< stop
) {
118 boolean replaced
= false;
119 for (int i
= 0; i
< froms
.length
; i
++) {
121 && froms
[i
].length
> 0
123 .startsWith(froms
[i
], buffer
, start
, stop
)) {
124 if (tos
[i
] != null && tos
[i
].length
> 0) {
126 bytesWritten
+= tos
[i
].length
;
129 start
+= froms
[i
].length
;
136 out
.write(buffer
[start
++]);
144 if (includingSubStream
) {