f5138eefeafc327dbd865e3b89713843c027aa0a
[nikiroo-utils.git] / src / be / nikiroo / utils / streams / ReplaceInputStream.java
1 package be.nikiroo.utils.streams;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5
6 /**
7 * This {@link InputStream} will change some of its content by replacing it with
8 * something else.
9 *
10 * @author niki
11 */
12 public class ReplaceInputStream extends BufferedInputStream {
13 private byte[] from;
14 private byte[] to;
15
16 private byte[] source;
17 private int spos;
18 private int slen;
19
20 /**
21 * Create a {@link ReplaceInputStream} that will replace <tt>from</tt> with
22 * <tt>to</tt>.
23 *
24 * @param in
25 * the under-laying {@link InputStream}
26 * @param from
27 * the {@link String} to replace
28 * @param to
29 * the {@link String} to replace with
30 */
31 public ReplaceInputStream(InputStream in, String from, String to) {
32 this(in, StreamUtils.bytes(from), StreamUtils.bytes(to));
33 }
34
35 /**
36 * Create a {@link ReplaceInputStream} that will replace <tt>from</tt> with
37 * <tt>to</tt>.
38 *
39 * @param in
40 * the under-laying {@link InputStream}
41 * @param from
42 * the value to replace
43 * @param to
44 * the value to replace with
45 */
46 public ReplaceInputStream(InputStream in, byte[] from, byte[] to) {
47 super(in);
48 this.from = from;
49 this.to = to;
50
51 source = new byte[4096];
52 spos = 0;
53 slen = 0;
54 }
55
56 @Override
57 protected int read(InputStream in, byte[] buffer) throws IOException {
58 if (buffer.length < to.length || source.length < to.length * 2) {
59 throw new IOException(
60 "An underlaying buffer is too small for this replace value");
61 }
62
63 if (spos >= slen) {
64 spos = 0;
65 slen = in.read(source);
66 }
67
68 // Note: very simple, not efficient implementation, sorry.
69 int count = 0;
70 while (spos < slen && count < buffer.length - to.length) {
71 if (from.length > 0
72 && StreamUtils.startsWith(from, source, spos, slen)) {
73 System.arraycopy(to, 0, buffer, spos, to.length);
74 count += to.length;
75 spos += from.length;
76 } else {
77 buffer[count++] = source[spos++];
78 }
79 }
80
81 return count;
82 }
83 }