8342562: Enhance Deflater operations

Reviewed-by: rhalade, alanb, lancea
This commit is contained in:
Jaikiran Pai 2024-12-13 04:29:18 +00:00 committed by Jaikiran Pai
parent 43b2b0bd1e
commit cf871db447
2 changed files with 35 additions and 9 deletions

View File

@ -57,6 +57,26 @@ import java.io.IOException;
* @since 1.1
*/
public class DeflaterOutputStream extends FilterOutputStream {
/*
* The default size of the output buffer
*/
static final int DEFAULT_BUF_SIZE = 512;
/*
* When calling Deflater.deflate() with Deflater.SYNC_FLUSH or Deflater.FULL_FLUSH,
* the callers are expected to ensure that the size of the buffer is greater than 6.
* This expectation comes from the underlying zlib library which in its zlib.h
* states:
* "If deflate returns with avail_out == 0, this function must be called again
* with the same value of the flush parameter and more output space (updated
* avail_out), until the flush is complete (deflate returns with non-zero
* avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
* avail_out is greater than six when the flush marker begins, in order to avoid
* repeated flush markers upon calling deflate() again when avail_out == 0."
*/
private static final int SYNC_FLUSH_MIN_BUF_SIZE = 7;
/**
* Compressor for this stream.
*/
@ -152,7 +172,7 @@ public class DeflaterOutputStream extends FilterOutputStream {
public DeflaterOutputStream(OutputStream out,
Deflater def,
boolean syncFlush) {
this(out, def, 512, syncFlush);
this(out, def, DEFAULT_BUF_SIZE, syncFlush);
}
@ -171,7 +191,7 @@ public class DeflaterOutputStream extends FilterOutputStream {
* @param def the compressor ("deflater")
*/
public DeflaterOutputStream(OutputStream out, Deflater def) {
this(out, def, 512, false);
this(out, def, DEFAULT_BUF_SIZE, false);
}
boolean usesDefaultDeflater = false;
@ -195,7 +215,7 @@ public class DeflaterOutputStream extends FilterOutputStream {
* @since 1.7
*/
public DeflaterOutputStream(OutputStream out, boolean syncFlush) {
this(out, out != null ? new Deflater() : null, 512, syncFlush);
this(out, out != null ? new Deflater() : null, DEFAULT_BUF_SIZE, syncFlush);
usesDefaultDeflater = true;
}
@ -342,10 +362,16 @@ public class DeflaterOutputStream extends FilterOutputStream {
public void flush() throws IOException {
if (syncFlush && !def.finished()) {
int len = 0;
while ((len = def.deflate(buf, 0, buf.length, Deflater.SYNC_FLUSH)) > 0)
{
out.write(buf, 0, len);
if (len < buf.length)
// For SYNC_FLUSH, the Deflater.deflate() expects the callers
// to use a buffer whose length is greater than 6 to avoid
// flush marker (5 bytes) being repeatedly output to the output buffer
// every time it is invoked.
final byte[] flushBuf = buf.length < SYNC_FLUSH_MIN_BUF_SIZE
? new byte[DEFAULT_BUF_SIZE]
: buf;
while ((len = def.deflate(flushBuf, 0, flushBuf.length, Deflater.SYNC_FLUSH)) > 0) {
out.write(flushBuf, 0, len);
if (len < flushBuf.length)
break;
}
}

View File

@ -113,7 +113,7 @@ public class GZIPOutputStream extends DeflaterOutputStream {
* @throws IOException If an I/O error has occurred.
*/
public GZIPOutputStream(OutputStream out) throws IOException {
this(out, 512, false);
this(out, DeflaterOutputStream.DEFAULT_BUF_SIZE, false);
}
/**
@ -135,7 +135,7 @@ public class GZIPOutputStream extends DeflaterOutputStream {
public GZIPOutputStream(OutputStream out, boolean syncFlush)
throws IOException
{
this(out, 512, syncFlush);
this(out, DeflaterOutputStream.DEFAULT_BUF_SIZE, syncFlush);
}
/**