Commit | Line | Data |
---|---|---|
6ef54b36 NR |
1 | package be.nikiroo.utils; |
2 | ||
3 | import java.io.IOException; | |
4 | import java.io.InputStream; | |
5 | import java.io.UnsupportedEncodingException; | |
6 | ||
876dbf8b NR |
7 | /** |
8 | * This {@link InputStream} will replace some of its content by replacing it | |
9 | * with something else. | |
10 | * | |
11 | * @author niki | |
12 | */ | |
6ef54b36 NR |
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 | ||
876dbf8b NR |
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 | */ | |
6ef54b36 NR |
32 | public ReplaceInputStream(InputStream in, String from, String to) { |
33 | this(in, bytes(from), bytes(to)); | |
34 | } | |
35 | ||
876dbf8b NR |
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 | */ | |
6ef54b36 NR |
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 { | |
876dbf8b | 59 | if (buffer.length < to.length || source.length < to.length * 2) { |
6ef54b36 | 60 | throw new IOException( |
876dbf8b | 61 | "An underlaying buffer is too small for this replace value"); |
6ef54b36 NR |
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; | |
876dbf8b | 71 | while (spos < slen && count < buffer.length - to.length) { |
eeaa5ebc | 72 | if (from.length > 0 && startsWith(from, source, spos, slen)) { |
6ef54b36 NR |
73 | System.arraycopy(to, 0, buffer, spos, to.length); |
74 | count += to.length; | |
876dbf8b | 75 | spos += from.length; |
6ef54b36 | 76 | } else { |
876dbf8b | 77 | buffer[count++] = source[spos++]; |
6ef54b36 NR |
78 | } |
79 | } | |
80 | ||
81 | return count; | |
82 | } | |
83 | ||
876dbf8b NR |
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 | */ | |
6ef54b36 NR |
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 | } |