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 java.io.IOException; | |
22 | import java.io.OutputStream; | |
23 | ||
24 | import javax.annotation.concurrent.NotThreadSafe; | |
25 | ||
26 | /** | |
27 | * A search and replace filtering {@link OutputStream} wrapper | |
28 | * | |
29 | * @see ReplaceAllInputStream | |
30 | */ | |
31 | @SuppressWarnings("squid:S4349") // Sonar: Not applicable IMO | |
32 | @NotThreadSafe | |
33 | public final class ReplaceAllOutputStream extends OutputStream { | |
34 | ||
35 | private final byte[] search; | |
36 | private final byte[] replace; | |
37 | private final OutputStream wrapped; | |
38 | private int position; | |
39 | ||
40 | ||
41 | /** | |
42 | * Create a new {@link ReplaceAllOutputStream} | |
43 | * | |
44 | * @param search the byte sequence to search for | |
45 | * @param replace the replacement byte sequence to substitute when the {@code search} sequence if found | |
46 | * @param output the {@link OutputStream} to operate on | |
47 | */ | |
48 | public ReplaceAllOutputStream(byte[] search, byte[] replace, OutputStream output) | |
49 | { | |
50 | this.search = search; | |
51 | this.replace = replace; | |
52 | this.wrapped = output; | |
53 | this.position = 0; | |
54 | } | |
55 | ||
56 | ||
57 | @Override | |
58 | public void write(int b) throws IOException | |
59 | { | |
60 |
1
1. write : negated conditional → KILLED |
if(position == search.length) { |
61 |
1
1. write : removed call to java/io/OutputStream::write → KILLED |
wrapped.write(replace); |
62 | position = 0; | |
63 | } | |
64 |
1
1. write : negated conditional → KILLED |
if(search[position] == b) { |
65 |
1
1. write : Replaced integer addition with subtraction → KILLED |
++position; |
66 | } else { | |
67 |
1
1. write : removed call to java/io/OutputStream::write → KILLED |
wrapped.write(search, 0, position); |
68 |
1
1. write : removed call to java/io/OutputStream::write → KILLED |
wrapped.write(b); |
69 | position = 0; | |
70 | } | |
71 | } | |
72 | ||
73 | ||
74 | @Override | |
75 | public void close() throws IOException | |
76 | { | |
77 |
2
1. close : changed conditional boundary → SURVIVED 2. close : negated conditional → KILLED |
if(position > 0) { |
78 |
1
1. close : removed call to java/io/OutputStream::write → KILLED |
wrapped.write(search, 0, position); |
79 | } | |
80 |
1
1. close : removed call to java/io/OutputStream::close → KILLED |
wrapped.close(); |
81 | } | |
82 | } | |
Mutations | ||
60 |
1.1 |
|
61 |
1.1 |
|
64 |
1.1 |
|
65 |
1.1 |
|
67 |
1.1 |
|
68 |
1.1 |
|
77 |
1.1 2.2 |
|
78 |
1.1 |
|
80 |
1.1 |