ReplaceStreams: allow multiple replacements strings
[nikiroo-utils.git] / src / be / nikiroo / utils / streams / ReplaceOutputStream.java
CommitLineData
c8ce09c4
NR
1package be.nikiroo.utils.streams;
2
3import java.io.IOException;
4import java.io.OutputStream;
5
6/**
7 * This {@link OutputStream} will change some of its content by replacing it
8 * with something else.
9 *
10 * @author niki
11 */
12public class ReplaceOutputStream extends BufferedOutputStream {
627f866e
NR
13 private byte[][] froms;
14 private byte[][] tos;
c8ce09c4
NR
15
16 /**
17 * Create a {@link ReplaceOutputStream} that will replace <tt>from</tt> with
18 * <tt>to</tt>.
19 *
20 * @param out
21 * the under-laying {@link OutputStream}
22 * @param from
23 * the {@link String} to replace
24 * @param to
25 * the {@link String} to replace with
26 */
27 public ReplaceOutputStream(OutputStream out, String from, String to) {
28 this(out, StreamUtils.bytes(from), StreamUtils.bytes(to));
29 }
30
31 /**
32 * Create a {@link ReplaceOutputStream} that will replace <tt>from</tt> with
33 * <tt>to</tt>.
34 *
35 * @param out
36 * the under-laying {@link OutputStream}
37 * @param from
38 * the value to replace
39 * @param to
40 * the value to replace with
41 */
42 public ReplaceOutputStream(OutputStream out, byte[] from, byte[] to) {
627f866e
NR
43 this(out, new byte[][] { from }, new byte[][] { to });
44 }
45
46 /**
47 * Create a {@link ReplaceOutputStream} that will replace all <tt>froms</tt>
48 * with <tt>tos</tt>.
49 * <p>
50 * Note that they will be replaced in order, and that for each <tt>from</tt>
51 * a <tt>to</tt> must correspond.
52 *
53 * @param out
54 * the under-laying {@link OutputStream}
55 * @param froms
56 * the values to replace
57 * @param tos
58 * the values to replace with
59 */
60 public ReplaceOutputStream(OutputStream out, String[] froms, String[] tos) {
61 this(out, StreamUtils.bytes(froms), StreamUtils.bytes(tos));
62 }
63
64 /**
65 * Create a {@link ReplaceOutputStream} that will replace all <tt>froms</tt>
66 * with <tt>tos</tt>.
67 * <p>
68 * Note that they will be replaced in order, and that for each <tt>from</tt>
69 * a <tt>to</tt> must correspond.
70 *
71 * @param out
72 * the under-laying {@link OutputStream}
73 * @param froms
74 * the values to replace
75 * @param tos
76 * the values to replace with
77 */
78 public ReplaceOutputStream(OutputStream out, byte[][] froms, byte[][] tos) {
c8ce09c4
NR
79 super(out);
80 bypassFlush = false;
81
627f866e
NR
82 if (froms.length != tos.length) {
83 throw new IllegalArgumentException(
84 "For replacing, each FROM must have a corresponding TO");
85 }
86
87 this.froms = froms;
88 this.tos = tos;
c8ce09c4
NR
89 }
90
91 @Override
92 protected void flush(boolean includingSubStream) throws IOException {
93 // Note: very simple, not efficient implementation, sorry.
94 while (start < stop) {
627f866e
NR
95 boolean replaced = false;
96 for (int i = 0; i < froms.length; i++) {
97 if (froms[i] != null
98 && froms[i].length > 0
99 && StreamUtils
100 .startsWith(froms[i], buffer, start, stop)) {
101 if (tos[i] != null && tos[i].length > 0) {
102 out.write(tos[i]);
103 bytesWritten += tos[i].length;
104 }
105
106 start += froms[i].length;
107 replaced = true;
108 break;
109 }
110 }
111
112 if (!replaced) {
c8ce09c4
NR
113 out.write(buffer[start++]);
114 bytesWritten++;
115 }
116 }
117
118 start = 0;
119 stop = 0;
120
121 if (includingSubStream) {
122 out.flush();
123 }
124 }
125}