mirror of
https://github.com/exituser/Brewery.git
synced 2026-09-17 05:28:59 +00:00
148 lines
3.2 KiB
Java
148 lines
3.2 KiB
Java
package com.dre.brewery.lore;
|
|
|
|
import java.io.FilterInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
|
|
public class Base91DecoderStream extends FilterInputStream {
|
|
|
|
private final basE91 decoder = new basE91();
|
|
private byte[] decbuf = new byte[32];
|
|
private byte[] buf = new byte[32];
|
|
private int reader = 0;
|
|
private int count = 0;
|
|
private byte[] markBuf = null;
|
|
|
|
public Base91DecoderStream(InputStream in) {
|
|
super(in);
|
|
}
|
|
|
|
private void decode() throws IOException {
|
|
reader = 0;
|
|
count = in.read(decbuf);
|
|
if (count < 1) {
|
|
count = decoder.decEnd(buf);
|
|
if (count < 1) {
|
|
count = -1;
|
|
}
|
|
return;
|
|
}
|
|
count = decoder.decode(decbuf, count, buf);
|
|
}
|
|
|
|
@Override
|
|
public int read() throws IOException {
|
|
if (count == -1) return -1;
|
|
if (count == 0 || reader == count) {
|
|
decode();
|
|
return read();
|
|
}
|
|
return buf[reader++] & 0xFF;
|
|
}
|
|
|
|
@Override
|
|
public int read(byte[] b, int off, int len) throws IOException {
|
|
if (b == null) throw new NullPointerException();
|
|
if (off < 0 || len < 0 || len > b.length - off) throw new IndexOutOfBoundsException();
|
|
if (len == 0) return 0;
|
|
|
|
if (count == -1) return -1;
|
|
if (count == 0 || reader == count) {
|
|
decode();
|
|
if (count == -1) return -1;
|
|
}
|
|
|
|
if (count > 0 && count - reader >= len) {
|
|
// enough data in buffer, copy it out directly
|
|
System.arraycopy(buf, reader, b, off, len);
|
|
reader += len;
|
|
return len;
|
|
}
|
|
|
|
int out = 0;
|
|
int writeSize;
|
|
while (count > 0) {
|
|
// Not enough data in buffer, write all out, decode and repeat
|
|
writeSize = Math.min(len, count - reader);
|
|
System.arraycopy(buf, reader, b, off + out, writeSize);
|
|
out += writeSize;
|
|
len -= writeSize;
|
|
if (len > 0) {
|
|
decode();
|
|
} else {
|
|
reader += writeSize;
|
|
break;
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
@Override
|
|
public long skip(long n) throws IOException {
|
|
if (count == -1) return 0;
|
|
if (count > 0 && count - reader >= n) {
|
|
reader += n;
|
|
return n;
|
|
}
|
|
long skipped = count - reader;
|
|
decode();
|
|
|
|
while (count > 0) {
|
|
if (count > n - skipped) {
|
|
reader = (int) (n - skipped);
|
|
return n;
|
|
}
|
|
skipped += count;
|
|
decode();
|
|
}
|
|
return skipped;
|
|
}
|
|
|
|
@Override
|
|
public int available() throws IOException {
|
|
if (count == -1) return 0;
|
|
return (int) (in.available() * 0.813F) + count - reader; // Ratio encoded to decoded with random data
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
in.close();
|
|
count = -1;
|
|
decoder.decReset();
|
|
buf = null;
|
|
decbuf = null;
|
|
}
|
|
|
|
@Override
|
|
public synchronized void mark(int readlimit) {
|
|
if (!markSupported()) return;
|
|
if (count == -1) return;
|
|
in.mark(readlimit);
|
|
decoder.decMark();
|
|
if (count > 0 && reader < count) {
|
|
markBuf = new byte[count - reader];
|
|
System.arraycopy(buf, reader, markBuf, 0, markBuf.length);
|
|
} else {
|
|
markBuf = null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public synchronized void reset() throws IOException {
|
|
if (!markSupported()) throw new IOException("mark and reset not supported by underlying Stream");
|
|
in.reset();
|
|
decoder.decUnmark();
|
|
reader = 0;
|
|
count = 0;
|
|
if (markBuf != null) {
|
|
System.arraycopy(markBuf, 0, buf, 0, markBuf.length);
|
|
count = markBuf.length;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean markSupported() {
|
|
return in.markSupported();
|
|
}
|
|
}
|