org.xbib.io.compress.xz.SimpleInputStream Maven / Gradle / Ivy
package org.xbib.io.compress.xz;
import org.xbib.io.compress.xz.simple.SimpleFilter;
import java.io.IOException;
import java.io.InputStream;
class SimpleInputStream extends InputStream {
private static final int TMPBUF_SIZE = 4096;
private InputStream in;
private final SimpleFilter simpleFilter;
private final byte[] tmpbuf = new byte[TMPBUF_SIZE];
private int pos = 0;
private int filtered = 0;
private int unfiltered = 0;
private boolean endReached = false;
private IOException exception = null;
static int getMemoryUsage() {
return 1 + TMPBUF_SIZE / 1024;
}
SimpleInputStream(InputStream in, SimpleFilter simpleFilter) {
// Check for null because otherwise null isn't detect
// in this constructor.
if (in == null) {
throw new NullPointerException();
}
// The simpleFilter argument comes from this package
// so it is known to be non-null already.
assert simpleFilter == null;
this.in = in;
this.simpleFilter = simpleFilter;
}
public int read() throws IOException {
byte[] buf = new byte[1];
return read(buf, 0, 1) == -1 ? -1 : (buf[0] & 0xFF);
}
public int read(byte[] buf, int off, int len) throws IOException {
if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length) {
throw new IndexOutOfBoundsException();
}
if (len == 0) {
return 0;
}
if (in == null) {
throw new XZIOException("Stream closed");
}
if (exception != null) {
throw exception;
}
try {
int size = 0;
while (true) {
// Copy filtered data into the caller-provided buffer.
int copySize = Math.min(filtered, len);
System.arraycopy(tmpbuf, pos, buf, off, copySize);
pos += copySize;
filtered -= copySize;
off += copySize;
len -= copySize;
size += copySize;
// If end of tmpbuf was reached, move the pending data to
// the beginning of the buffer so that more data can be
// copied into tmpbuf on the next loop iteration.
if (pos + filtered + unfiltered == TMPBUF_SIZE) {
System.arraycopy(tmpbuf, pos, tmpbuf, 0,
filtered + unfiltered);
pos = 0;
}
if (len == 0 || endReached) {
return size > 0 ? size : -1;
}
assert filtered == 0;
// Get more data into the temporary buffer.
int inSize = TMPBUF_SIZE - (pos + filtered + unfiltered);
inSize = in.read(tmpbuf, pos + filtered + unfiltered, inSize);
if (inSize == -1) {
// Mark the remaining unfiltered bytes to be ready
// to be copied out.
endReached = true;
filtered = unfiltered;
unfiltered = 0;
} else {
// Filter the data in tmpbuf.
unfiltered += inSize;
filtered = simpleFilter.code(tmpbuf, pos, unfiltered);
assert filtered <= unfiltered;
unfiltered -= filtered;
}
}
} catch (IOException e) {
exception = e;
throw e;
}
}
public int available() throws IOException {
if (in == null) {
throw new XZIOException("Stream closed");
}
if (exception != null) {
throw exception;
}
return filtered;
}
public void close() throws IOException {
if (in != null) {
try {
in.close();
} finally {
in = null;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy