Skip to content

Commit cf871db

Browse files
committed
8342562: Enhance Deflater operations
Reviewed-by: rhalade, alanb, lancea
1 parent 43b2b0b commit cf871db

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

src/java.base/share/classes/java/util/zip/DeflaterOutputStream.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,26 @@
5757
* @since 1.1
5858
*/
5959
public class DeflaterOutputStream extends FilterOutputStream {
60+
61+
/*
62+
* The default size of the output buffer
63+
*/
64+
static final int DEFAULT_BUF_SIZE = 512;
65+
66+
/*
67+
* When calling Deflater.deflate() with Deflater.SYNC_FLUSH or Deflater.FULL_FLUSH,
68+
* the callers are expected to ensure that the size of the buffer is greater than 6.
69+
* This expectation comes from the underlying zlib library which in its zlib.h
70+
* states:
71+
* "If deflate returns with avail_out == 0, this function must be called again
72+
* with the same value of the flush parameter and more output space (updated
73+
* avail_out), until the flush is complete (deflate returns with non-zero
74+
* avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
75+
* avail_out is greater than six when the flush marker begins, in order to avoid
76+
* repeated flush markers upon calling deflate() again when avail_out == 0."
77+
*/
78+
private static final int SYNC_FLUSH_MIN_BUF_SIZE = 7;
79+
6080
/**
6181
* Compressor for this stream.
6282
*/
@@ -152,7 +172,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def, int size) {
152172
public DeflaterOutputStream(OutputStream out,
153173
Deflater def,
154174
boolean syncFlush) {
155-
this(out, def, 512, syncFlush);
175+
this(out, def, DEFAULT_BUF_SIZE, syncFlush);
156176
}
157177

158178

@@ -171,7 +191,7 @@ public DeflaterOutputStream(OutputStream out,
171191
* @param def the compressor ("deflater")
172192
*/
173193
public DeflaterOutputStream(OutputStream out, Deflater def) {
174-
this(out, def, 512, false);
194+
this(out, def, DEFAULT_BUF_SIZE, false);
175195
}
176196

177197
boolean usesDefaultDeflater = false;
@@ -195,7 +215,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def) {
195215
* @since 1.7
196216
*/
197217
public DeflaterOutputStream(OutputStream out, boolean syncFlush) {
198-
this(out, out != null ? new Deflater() : null, 512, syncFlush);
218+
this(out, out != null ? new Deflater() : null, DEFAULT_BUF_SIZE, syncFlush);
199219
usesDefaultDeflater = true;
200220
}
201221

@@ -342,10 +362,16 @@ protected void deflate() throws IOException {
342362
public void flush() throws IOException {
343363
if (syncFlush && !def.finished()) {
344364
int len = 0;
345-
while ((len = def.deflate(buf, 0, buf.length, Deflater.SYNC_FLUSH)) > 0)
346-
{
347-
out.write(buf, 0, len);
348-
if (len < buf.length)
365+
// For SYNC_FLUSH, the Deflater.deflate() expects the callers
366+
// to use a buffer whose length is greater than 6 to avoid
367+
// flush marker (5 bytes) being repeatedly output to the output buffer
368+
// every time it is invoked.
369+
final byte[] flushBuf = buf.length < SYNC_FLUSH_MIN_BUF_SIZE
370+
? new byte[DEFAULT_BUF_SIZE]
371+
: buf;
372+
while ((len = def.deflate(flushBuf, 0, flushBuf.length, Deflater.SYNC_FLUSH)) > 0) {
373+
out.write(flushBuf, 0, len);
374+
if (len < flushBuf.length)
349375
break;
350376
}
351377
}

src/java.base/share/classes/java/util/zip/GZIPOutputStream.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public GZIPOutputStream(OutputStream out, int size, boolean syncFlush)
113113
* @throws IOException If an I/O error has occurred.
114114
*/
115115
public GZIPOutputStream(OutputStream out) throws IOException {
116-
this(out, 512, false);
116+
this(out, DeflaterOutputStream.DEFAULT_BUF_SIZE, false);
117117
}
118118

119119
/**
@@ -135,7 +135,7 @@ public GZIPOutputStream(OutputStream out) throws IOException {
135135
public GZIPOutputStream(OutputStream out, boolean syncFlush)
136136
throws IOException
137137
{
138-
this(out, 512, syncFlush);
138+
this(out, DeflaterOutputStream.DEFAULT_BUF_SIZE, syncFlush);
139139
}
140140

141141
/**

0 commit comments

Comments
 (0)