Commit | Line | Data |
---|---|---|
8e76f6ab | 1 | package be.nikiroo.utils.streams; |
6ef54b36 NR |
2 | |
3 | import java.io.IOException; | |
4 | import java.io.InputStream; | |
6ef54b36 | 5 | |
876dbf8b | 6 | /** |
c8ce09c4 NR |
7 | * This {@link InputStream} will change some of its content by replacing it with |
8 | * something else. | |
876dbf8b NR |
9 | * |
10 | * @author niki | |
11 | */ | |
6ef54b36 NR |
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 | ||
876dbf8b NR |
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 | */ | |
6ef54b36 | 31 | public ReplaceInputStream(InputStream in, String from, String to) { |
c8ce09c4 | 32 | this(in, StreamUtils.bytes(from), StreamUtils.bytes(to)); |
6ef54b36 NR |
33 | } |
34 | ||
876dbf8b NR |
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 | */ | |
6ef54b36 NR |
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 { | |
876dbf8b | 58 | if (buffer.length < to.length || source.length < to.length * 2) { |
6ef54b36 | 59 | throw new IOException( |
876dbf8b | 60 | "An underlaying buffer is too small for this replace value"); |
6ef54b36 NR |
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; | |
876dbf8b | 70 | while (spos < slen && count < buffer.length - to.length) { |
c8ce09c4 NR |
71 | if (from.length > 0 |
72 | && StreamUtils.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 | } | |
6ef54b36 | 83 | } |