1 package be
.nikiroo
.utils
.streams
;
3 import java
.io
.IOException
;
4 import java
.io
.OutputStream
;
7 * This {@link OutputStream} will change some of its content by replacing it
12 public class ReplaceOutputStream
extends BufferedOutputStream
{
13 private byte[][] froms
;
17 * Create a {@link ReplaceOutputStream} that will replace <tt>from</tt> with
21 * the under-laying {@link OutputStream}
23 * the {@link String} to replace
25 * the {@link String} to replace with
27 public ReplaceOutputStream(OutputStream out
, String from
, String to
) {
28 this(out
, StreamUtils
.bytes(from
), StreamUtils
.bytes(to
));
32 * Create a {@link ReplaceOutputStream} that will replace <tt>from</tt> with
36 * the under-laying {@link OutputStream}
38 * the value to replace
40 * the value to replace with
42 public ReplaceOutputStream(OutputStream out
, byte[] from
, byte[] to
) {
43 this(out
, new byte[][] { from
}, new byte[][] { to
});
47 * Create a {@link ReplaceOutputStream} that will replace all <tt>froms</tt>
50 * Note that they will be replaced in order, and that for each <tt>from</tt>
51 * a <tt>to</tt> must correspond.
54 * the under-laying {@link OutputStream}
56 * the values to replace
58 * the values to replace with
60 public ReplaceOutputStream(OutputStream out
, String
[] froms
, String
[] tos
) {
61 this(out
, StreamUtils
.bytes(froms
), StreamUtils
.bytes(tos
));
65 * Create a {@link ReplaceOutputStream} that will replace all <tt>froms</tt>
68 * Note that they will be replaced in order, and that for each <tt>from</tt>
69 * a <tt>to</tt> must correspond.
72 * the under-laying {@link OutputStream}
74 * the values to replace
76 * the values to replace with
78 public ReplaceOutputStream(OutputStream out
, byte[][] froms
, byte[][] tos
) {
82 if (froms
.length
!= tos
.length
) {
83 throw new IllegalArgumentException(
84 "For replacing, each FROM must have a corresponding TO");
92 * Flush the {@link BufferedOutputStream}, write the current buffered data
93 * to (and optionally also flush) the under-laying stream.
95 * If {@link BufferedOutputStream#bypassFlush} is false, all writes to the
96 * under-laying stream are done in this method.
98 * This can be used if you want to write some data in the under-laying
99 * stream yourself (in that case, flush this {@link BufferedOutputStream}
100 * with or without flushing the under-laying stream, then you can write to
101 * the under-laying stream).
103 * <b>But be careful!</b> If a replacement could be done with the end o the
104 * currently buffered data and the start of the data to come, we obviously
105 * will not be able to do it.
107 * @param includingSubStream
108 * also flush the under-laying stream
109 * @throws IOException
110 * in case of I/O error
113 public void flush(boolean includingSubStream
) throws IOException
{
114 // Note: very simple, not efficient implementation; sorry.
115 while (start
< stop
) {
116 boolean replaced
= false;
117 for (int i
= 0; i
< froms
.length
; i
++) {
119 && froms
[i
].length
> 0
121 .startsWith(froms
[i
], buffer
, start
, stop
)) {
122 if (tos
[i
] != null && tos
[i
].length
> 0) {
124 bytesWritten
+= tos
[i
].length
;
127 start
+= froms
[i
].length
;
134 out
.write(buffer
[start
++]);
142 if (includingSubStream
) {