1 | /*- | |
2 | * #%L | |
3 | * io.earcam.utilitarian.io | |
4 | * %% | |
5 | * Copyright (C) 2017 earcam | |
6 | * %% | |
7 | * SPDX-License-Identifier: (BSD-3-Clause OR EPL-1.0 OR Apache-2.0 OR MIT) | |
8 | * | |
9 | * You <b>must</b> choose to accept, in full - any individual or combination of | |
10 | * the following licenses: | |
11 | * <ul> | |
12 | * <li><a href="https://opensource.org/licenses/BSD-3-Clause">BSD-3-Clause</a></li> | |
13 | * <li><a href="https://www.eclipse.org/legal/epl-v10.html">EPL-1.0</a></li> | |
14 | * <li><a href="https://www.apache.org/licenses/LICENSE-2.0">Apache-2.0</a></li> | |
15 | * <li><a href="https://opensource.org/licenses/MIT">MIT</a></li> | |
16 | * </ul> | |
17 | * #L% | |
18 | */ | |
19 | package io.earcam.utilitarian.io; | |
20 | ||
21 | import static io.earcam.utilitarian.io.MarkSupportedInputStream.ensureMarkSupported; | |
22 | ||
23 | import java.io.IOException; | |
24 | import java.io.InputStream; | |
25 | ||
26 | import javax.annotation.concurrent.NotThreadSafe; | |
27 | ||
28 | /** | |
29 | * <p> | |
30 | * A search and replace filtering {@link InputStream} wrapper. | |
31 | * </p> | |
32 | * | |
33 | * <p> | |
34 | * Requires the underlying {@link InputStream} supports mark and reset; so uses | |
35 | * {@link MarkSupportedInputStream#ensureMarkSupported(InputStream)} to guarantee | |
36 | * this prerequisite. | |
37 | * </p> | |
38 | * | |
39 | * @see ReplaceAllOutputStream | |
40 | */ | |
41 | @NotThreadSafe | |
42 | public final class ReplaceAllInputStream extends InputStream { | |
43 | ||
44 | private static final int UNPOSITIONED = -1; | |
45 | private final byte[] search; | |
46 | private final byte[] replace; | |
47 | private final InputStream wrapped; | |
48 | private int position = UNPOSITIONED; | |
49 | ||
50 | ||
51 | /** | |
52 | * Create a new {@link ReplaceAllInputStream} | |
53 | * | |
54 | * @param search the byte sequence to search for | |
55 | * @param replace the replacement byte sequence to substitute when the {@code search} sequence if found | |
56 | * @param input the {@link InputStream} to operate on | |
57 | */ | |
58 | public ReplaceAllInputStream(byte[] search, byte[] replace, InputStream input) | |
59 | { | |
60 | this.search = search; | |
61 | this.replace = replace; | |
62 | this.wrapped = ensureMarkSupported(input); | |
63 | } | |
64 | ||
65 | ||
66 | @Override | |
67 | public int read() throws IOException | |
68 | { | |
69 |
3
1. read : changed conditional boundary → KILLED 2. read : negated conditional → KILLED 3. read : negated conditional → KILLED |
if(position != UNPOSITIONED && position < replace.length) { |
70 |
3
1. read : Replaced integer addition with subtraction → KILLED 2. read : Replaced bitwise AND with OR → KILLED 3. read : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return replace[position++] & 0xFF; |
71 | } | |
72 | int read = wrapped.read(); | |
73 |
1
1. read : negated conditional → KILLED |
if(read == search[0]) { |
74 |
1
1. read : removed call to java/io/InputStream::mark → KILLED |
wrapped.mark(search.length); |
75 | int p = search(); | |
76 |
1
1. read : negated conditional → KILLED |
if(p == search.length) { |
77 | position = 1; | |
78 |
3
1. read : Replaced bitwise AND with OR → KILLED 2. read : negated conditional → KILLED 3. read : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return replace.length == 0 ? read() : (replace[0] & 0xFF); |
79 | } else { | |
80 |
1
1. read : removed call to java/io/InputStream::reset → KILLED |
wrapped.reset(); |
81 | } | |
82 | } | |
83 | position = UNPOSITIONED; | |
84 |
1
1. read : replaced return of integer sized value with (x == 0 ? 1 : 0) → TIMED_OUT |
return read; |
85 | } | |
86 | ||
87 | ||
88 | private int search() throws IOException | |
89 | { | |
90 | int p = 1; | |
91 |
3
1. search : changed conditional boundary → KILLED 2. search : negated conditional → KILLED 3. search : negated conditional → KILLED |
while(p < search.length && wrapped.read() == search[p]) { |
92 |
1
1. search : Changed increment from 1 to -1 → KILLED |
++p; |
93 | } | |
94 |
1
1. search : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return p; |
95 | } | |
96 | } | |
Mutations | ||
69 |
1.1 2.2 3.3 |
|
70 |
1.1 2.2 3.3 |
|
73 |
1.1 |
|
74 |
1.1 |
|
76 |
1.1 |
|
78 |
1.1 2.2 3.3 |
|
80 |
1.1 |
|
84 |
1.1 |
|
91 |
1.1 2.2 3.3 |
|
92 |
1.1 |
|
94 |
1.1 |