diff --git a/classpath/java-util-zip.cpp b/classpath/java-util-zip.cpp index a7d969839a..f883e528bc 100644 --- a/classpath/java-util-zip.cpp +++ b/classpath/java-util-zip.cpp @@ -121,7 +121,7 @@ Java_java_util_zip_Deflater_deflate (JNIEnv* e, jclass, jlong peer, jbyteArray input, jint inputOffset, jint inputLength, jbyteArray output, jint outputOffset, jint outputLength, - jintArray results) + jboolean finish, jintArray results) { z_stream* s = reinterpret_cast(peer); @@ -145,7 +145,7 @@ Java_java_util_zip_Deflater_deflate s->next_out = reinterpret_cast(out); s->avail_out = outputLength; - int r = deflate(s, Z_SYNC_FLUSH); + int r = deflate(s, finish ? Z_FINISH : Z_NO_FLUSH); jint resultArray[3] = { r, inputLength - s->avail_in, outputLength - s->avail_out }; diff --git a/classpath/java/util/zip/Deflater.java b/classpath/java/util/zip/Deflater.java index d7bfc83b88..28df9754d2 100644 --- a/classpath/java/util/zip/Deflater.java +++ b/classpath/java/util/zip/Deflater.java @@ -27,14 +27,19 @@ public class Deflater { private boolean needDictionary; private boolean finished; private final boolean nowrap; + private boolean finish; - public Deflater(boolean nowrap) { + public Deflater(int level, boolean nowrap) { this.nowrap = nowrap; - peer = make(nowrap, DEFAULT_LEVEL); + peer = make(nowrap, level); + } + + public Deflater(int level) { + this(level, false); } public Deflater() { - this(false); + this(DEFAULT_LEVEL); } private void check() { @@ -85,16 +90,15 @@ public class Deflater { peer = make(nowrap, DEFAULT_LEVEL); input = null; offset = length = 0; + finish = false; needDictionary = finished = false; } - public int deflate(byte[] output) throws DataFormatException { + public int deflate(byte[] output) { return deflate(output, 0, output.length); } - public int deflate(byte[] output, int offset, int length) - throws DataFormatException - { + public int deflate(byte[] output, int offset, int length) { final int zlibResult = 0; final int inputCount = 1; final int outputCount = 2; @@ -110,10 +114,10 @@ public class Deflater { int[] results = new int[3]; deflate(peer, input, this.offset, this.length, - output, offset, length, results); + output, offset, length, finish, results); if (results[zlibResult] < 0) { - throw new DataFormatException(); + throw new AssertionError(); } switch (results[zlibResult]) { @@ -132,10 +136,15 @@ public class Deflater { return results[outputCount]; } + public void finish() { + finish = true; + } + private static native void deflate (long peer, byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength, + boolean finish, int[] results); public void dispose() { diff --git a/classpath/java/util/zip/DeflaterOutputStream.java b/classpath/java/util/zip/DeflaterOutputStream.java index e55668e53c..3ee3fcdbb8 100644 --- a/classpath/java/util/zip/DeflaterOutputStream.java +++ b/classpath/java/util/zip/DeflaterOutputStream.java @@ -52,23 +52,25 @@ public class DeflaterOutputStream extends OutputStream { } else if (length == 0) { return; } - - for (int i = 0; i < length; i+= buffer.length) { - deflater.setInput(b, offset + i, Math.min(buffer.length, length - i)); - while (deflater.getRemaining() > 0) { - try { - int len = deflater.deflate(buffer, 0, buffer.length); - if (len > 0) { - out.write(buffer, 0, len); - } - } catch (DataFormatException e) { - e.printStackTrace(); - } - } + + deflater.setInput(b, offset, length); + while (deflater.getRemaining() > 0) { + deflate(); + } + } + + private void deflate() throws IOException { + int len = deflater.deflate(buffer, 0, buffer.length); + if (len > 0) { + out.write(buffer, 0, len); } } public void close() throws IOException { + deflater.finish(); + while (! deflater.finished()) { + deflate(); + } out.close(); deflater.dispose(); }