Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/sourcetools/com.ibm.jpp.preprocessor/com/ibm/jpp/om/PhantomOutputStream.java
6004 views
1
/*******************************************************************************
2
* Copyright (c) 1999, 2017 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
package com.ibm.jpp.om;
23
24
import java.io.BufferedOutputStream;
25
import java.io.ByteArrayOutputStream;
26
import java.io.File;
27
import java.io.FileInputStream;
28
import java.io.FileNotFoundException;
29
import java.io.FileOutputStream;
30
import java.io.FilterOutputStream;
31
import java.io.IOException;
32
import java.io.InputStream;
33
import java.io.OutputStream;
34
35
public class PhantomOutputStream extends FilterOutputStream {
36
private final boolean forced;
37
private final File outputFile;
38
39
public PhantomOutputStream(File outputFile) {
40
this(outputFile, true);
41
}
42
43
public PhantomOutputStream(File outputFile, boolean forced) {
44
super(null);
45
this.forced = forced;
46
this.outputFile = outputFile;
47
}
48
49
@Override
50
public void close() throws IOException {
51
if (out != null) {
52
try {
53
super.close();
54
55
if (!forced) {
56
byte[] desired = ((ByteArrayOutputStream) out).toByteArray();
57
58
if (!fileMatches(desired)) {
59
try (OutputStream newOut = new FileOutputStream(outputFile)) {
60
newOut.write(desired);
61
}
62
}
63
}
64
} finally {
65
out = null;
66
}
67
}
68
}
69
70
private void createFile() throws IOException {
71
if (out == null) {
72
outputFile.getParentFile().mkdirs();
73
74
if (forced) {
75
out = new BufferedOutputStream(new FileOutputStream(outputFile), 32768);
76
} else {
77
out = new ByteArrayOutputStream();
78
}
79
}
80
}
81
82
private boolean fileMatches(byte[] desired) throws IOException {
83
try (InputStream existing = new FileInputStream(outputFile)) {
84
byte[] buffer = new byte[4096];
85
int offset = 0;
86
int remaining = desired.length;
87
88
for (;;) {
89
int count = existing.read(buffer);
90
91
if (count < 0) {
92
// EOF
93
return remaining == 0;
94
}
95
96
if (count > remaining) {
97
// the existing file is too long
98
return false;
99
}
100
101
for (int i = 0; i < count; ++i, ++offset) {
102
if (buffer[i] != desired[offset]) {
103
// we found a difference
104
return false;
105
}
106
}
107
108
remaining -= count;
109
}
110
} catch (FileNotFoundException e) {
111
// the file does not exist
112
return false;
113
}
114
}
115
116
@Override
117
public void flush() throws IOException {
118
if (out != null) {
119
super.flush();
120
}
121
}
122
123
@Override
124
public void write(byte[] buffer, int offset, int length) throws IOException {
125
createFile();
126
out.write(buffer, offset, length);
127
}
128
129
@Override
130
public void write(int value) throws IOException {
131
createFile();
132
out.write(value);
133
}
134
135
}
136
137