change package for Streams to nikiroo.utils.streams
[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 import java.io.UnsupportedEncodingException;
6
7 /**
8 * This {@link InputStream} will replace some of its content by replacing it
9 * with something else.
10 *
11 * @author niki
12 */
13 public class ReplaceInputStream extends BufferedInputStream {
14 private byte[] from;
15 private byte[] to;
16
17 private byte[] source;
18 private int spos;
19 private int slen;
20
21 /**
22 * Create a {@link ReplaceInputStream} that will replace <tt>from</tt> with
23 * <tt>to</tt>.
24 *
25 * @param in
26 * the under-laying {@link InputStream}
27 * @param from
28 * the {@link String} to replace
29 * @param to
30 * the {@link String} to replace with
31 */
32 public ReplaceInputStream(InputStream in, String from, String to) {
33 this(in, bytes(from), bytes(to));
34 }
35
36 /**
37 * Create a {@link ReplaceInputStream} that will replace <tt>from</tt> with
38 * <tt>to</tt>.
39 *
40 * @param in
41 * the under-laying {@link InputStream}
42 * @param from
43 * the value to replace
44 * @param to
45 * the value to replace with
46 */
47 public ReplaceInputStream(InputStream in, byte[] from, byte[] to) {
48 super(in);
49 this.from = from;
50 this.to = to;
51
52 source = new byte[4096];
53 spos = 0;
54 slen = 0;
55 }
56
57 @Override
58 protected int read(InputStream in, byte[] buffer) throws IOException {
59 if (buffer.length < to.length || source.length < to.length * 2) {
60 throw new IOException(
61 "An underlaying buffer is too small for this replace value");
62 }
63
64 if (spos >= slen) {
65 spos = 0;
66 slen = in.read(source);
67 }
68
69 // Note: very simple, not efficient implementation, sorry.
70 int count = 0;
71 while (spos < slen && count < buffer.length - to.length) {
72 if (from.length > 0 && 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
84 /**
85 * Return the bytes array representation of the given {@link String} in
86 * UTF-8.
87 *
88 * @param str
89 * the string to transform into bytes
90 * @return the content in bytes
91 */
92 static private byte[] bytes(String str) {
93 try {
94 return str.getBytes("UTF-8");
95 } catch (UnsupportedEncodingException e) {
96 // All conforming JVM must support UTF-8
97 e.printStackTrace();
98 return null;
99 }
100 }
101 }