1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.commons.compress.compressors.pack200;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.UncheckedIOException;
26 import java.util.Map;
27 import java.util.jar.JarOutputStream;
28
29 import org.apache.commons.compress.compressors.CompressorInputStream;
30 import org.apache.commons.compress.java.util.jar.Pack200;
31 import org.apache.commons.io.input.CloseShieldInputStream;
32
33
34
35
36
37
38
39
40
41
42
43 public class Pack200CompressorInputStream extends CompressorInputStream {
44
45 private static final byte[] CAFE_DOOD = { (byte) 0xCA, (byte) 0xFE, (byte) 0xD0, (byte) 0x0D };
46 private static final int SIG_LENGTH = CAFE_DOOD.length;
47
48
49
50
51
52
53
54
55 public static boolean matches(final byte[] signature, final int length) {
56 if (length < SIG_LENGTH) {
57 return false;
58 }
59
60 for (int i = 0; i < SIG_LENGTH; i++) {
61 if (signature[i] != CAFE_DOOD[i]) {
62 return false;
63 }
64 }
65
66 return true;
67 }
68
69 private final InputStream originalInputStream;
70
71 private final AbstractStreamBridge abstractStreamBridge;
72
73
74
75
76
77
78
79 public Pack200CompressorInputStream(final File file) throws IOException {
80 this(file, Pack200Strategy.IN_MEMORY);
81 }
82
83
84
85
86
87
88
89
90 public Pack200CompressorInputStream(final File file, final Map<String, String> properties) throws IOException {
91 this(file, Pack200Strategy.IN_MEMORY, properties);
92 }
93
94
95
96
97
98
99
100
101 public Pack200CompressorInputStream(final File file, final Pack200Strategy mode) throws IOException {
102 this(null, file, mode, null);
103 }
104
105
106
107
108
109
110
111
112
113 public Pack200CompressorInputStream(final File file, final Pack200Strategy mode, final Map<String, String> properties) throws IOException {
114 this(null, file, mode, properties);
115 }
116
117
118
119
120
121
122
123
124
125
126
127 public Pack200CompressorInputStream(final InputStream inputStream) throws IOException {
128 this(inputStream, Pack200Strategy.IN_MEMORY);
129 }
130
131 private Pack200CompressorInputStream(final InputStream inputStream, final File file, final Pack200Strategy mode, final Map<String, String> properties)
132 throws IOException {
133 this.originalInputStream = inputStream;
134 this.abstractStreamBridge = mode.newStreamBridge();
135 try (JarOutputStream jarOut = new JarOutputStream(abstractStreamBridge)) {
136 final Pack200.Unpacker unpacker = Pack200.newUnpacker();
137 if (properties != null) {
138 unpacker.properties().putAll(properties);
139 }
140 if (file == null) {
141
142
143 try (CloseShieldInputStream closeShield = CloseShieldInputStream.wrap(inputStream)) {
144 unpacker.unpack(closeShield, jarOut);
145 }
146 } else {
147 unpacker.unpack(file, jarOut);
148 }
149 }
150 }
151
152
153
154
155
156
157
158
159
160
161
162
163 public Pack200CompressorInputStream(final InputStream inputStream, final Map<String, String> properties) throws IOException {
164 this(inputStream, Pack200Strategy.IN_MEMORY, properties);
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178 public Pack200CompressorInputStream(final InputStream inputStream, final Pack200Strategy mode) throws IOException {
179 this(inputStream, null, mode, null);
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193
194 public Pack200CompressorInputStream(final InputStream inputStream, final Pack200Strategy mode, final Map<String, String> properties) throws IOException {
195 this(inputStream, null, mode, properties);
196 }
197
198 @SuppressWarnings("resource")
199 @Override
200 public int available() throws IOException {
201 return getInputStream().available();
202 }
203
204 @Override
205 public void close() throws IOException {
206 try {
207 abstractStreamBridge.stop();
208 } finally {
209 if (originalInputStream != null) {
210 originalInputStream.close();
211 }
212 }
213 }
214
215 private InputStream getInputStream() throws IOException {
216 return abstractStreamBridge.getInputStream();
217 }
218
219 @SuppressWarnings("resource")
220 @Override
221 public synchronized void mark(final int limit) {
222 try {
223 getInputStream().mark(limit);
224 } catch (final IOException ex) {
225 throw new UncheckedIOException(ex);
226 }
227 }
228
229 @SuppressWarnings("resource")
230 @Override
231 public boolean markSupported() {
232 try {
233 return getInputStream().markSupported();
234 } catch (final IOException ex) {
235 return false;
236 }
237 }
238
239 @SuppressWarnings("resource")
240 @Override
241 public int read() throws IOException {
242 return getInputStream().read();
243 }
244
245 @SuppressWarnings("resource")
246 @Override
247 public int read(final byte[] b) throws IOException {
248 return getInputStream().read(b);
249 }
250
251 @SuppressWarnings("resource")
252 @Override
253 public int read(final byte[] b, final int off, final int count) throws IOException {
254 return getInputStream().read(b, off, count);
255 }
256
257 @SuppressWarnings("resource")
258 @Override
259 public synchronized void reset() throws IOException {
260 getInputStream().reset();
261 }
262
263 @SuppressWarnings("resource")
264 @Override
265 public long skip(final long count) throws IOException {
266 return org.apache.commons.io.IOUtils.skip(getInputStream(), count);
267 }
268 }