1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.node.admin.maintenance.sync;
import com.yahoo.compress.ZstdCompressor;
import java.io.IOException;
import java.io.InputStream;
/**
* InputStream that outputs given InputStream compressed with the ZStandard.
*
* @author freva
*/
public class ZstdCompressingInputStream extends InputStream {
public static final int DEFAULT_INPUT_BUFFER_SIZE = 8 * 1024;
static final ZstdCompressor compressor = new ZstdCompressor();
private final InputStream is;
private final byte[] inputBuffer;
private final byte[] outputBuffer;
private int outputPosition = 0;
private int outputLength = 0;
private boolean isClosed = false;
public ZstdCompressingInputStream(InputStream is, int inputBufferSize) {
this.is = is;
this.inputBuffer = new byte[inputBufferSize];
this.outputBuffer = new byte[ZstdCompressor.getMaxCompressedLength(inputBufferSize)];
}
public ZstdCompressingInputStream(InputStream is) {
this(is, DEFAULT_INPUT_BUFFER_SIZE);
}
@Override
public int read() throws IOException {
throwIfClosed();
if (outputPosition >= outputLength) {
int readLength = is.read(inputBuffer);
if (readLength == -1)
return -1;
outputLength = compressor.compress(inputBuffer, 0, readLength, outputBuffer, 0, outputBuffer.length);
outputPosition = 0;
}
return Byte.toUnsignedInt(outputBuffer[outputPosition++]);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int first = read();
if (first == -1) return -1;
b[off++] = (byte) first;
len = Math.min(Math.min(len, outputLength - outputPosition), b.length - off);
System.arraycopy(outputBuffer, outputPosition, b, off, len);
outputPosition += len;
return len + 1;
}
@Override
public void close() throws IOException {
throwIfClosed();
is.close();
isClosed = true;
}
private void throwIfClosed() {
if (isClosed) throw new IllegalArgumentException("Input stream is already closed");
}
}
|