@Override
public long compress(InputStream is, OutputStream os, long maxReadLength, long maxWriteLength) throws IOException, CompressionOutputSizeException {
if(maxReadLength <= 0)
throw new IllegalArgumentException();
BZip2CompressorOutputStream bz2os = null;
try {
CountedOutputStream cos = new CountedOutputStream(os);
bz2os = new BZip2CompressorOutputStream(HeaderStreams.dimOutput(BZ_HEADER, cos));
long read = 0;
// Bigger input buffer, so can compress all at once.
// Won't hurt on I/O either, although most OSs will only return a page at a time.
byte[] buffer = new byte[32768];
while(true) {
int l = (int) Math.min(buffer.length, maxReadLength - read);
int x = l == 0 ? -1 : is.read(buffer, 0, buffer.length);
if(x <= -1) break;
if(x == 0) throw new IOException("Returned zero from read()");
bz2os.write(buffer, 0, x);
read += x;
if(cos.written() > maxWriteLength)
throw new CompressionOutputSizeException();
}
bz2os.flush();
cos.flush();
bz2os.close();
bz2os = null;
if(cos.written() > maxWriteLength)
throw new CompressionOutputSizeException();
return cos.written();
} finally {
if(bz2os != null) {
bz2os.flush();
bz2os.close();
}
}
}