diff --git a/core/java/src/net/i2p/util/ResettableGZIPInputStream.java b/core/java/src/net/i2p/util/ResettableGZIPInputStream.java index 3411a4fce1..3114499927 100644 --- a/core/java/src/net/i2p/util/ResettableGZIPInputStream.java +++ b/core/java/src/net/i2p/util/ResettableGZIPInputStream.java @@ -168,6 +168,15 @@ public class ResettableGZIPInputStream extends InflaterInputStream { } } + /** + * Calls super.close(). May not be reused after this. + * @since 0.9.40 + */ + public void destroy() throws IOException { + close(); + super.close(); + } + /** * Does NOT call super.close(), as it cannot be reused if we do that. * Broken before 0.9.20. diff --git a/core/java/src/net/i2p/util/ResettableGZIPOutputStream.java b/core/java/src/net/i2p/util/ResettableGZIPOutputStream.java index cb9b461c8b..99b9fbd12e 100644 --- a/core/java/src/net/i2p/util/ResettableGZIPOutputStream.java +++ b/core/java/src/net/i2p/util/ResettableGZIPOutputStream.java @@ -18,6 +18,7 @@ import java.util.zip.DeflaterOutputStream; public class ResettableGZIPOutputStream extends DeflaterOutputStream { /** has the header been written out yet? */ private boolean _headerWritten; + private boolean _footerWritten; /** how much data is in the uncompressed stream? */ private long _writtenSize; private final CRC32 _crc32; @@ -39,6 +40,7 @@ public class ResettableGZIPOutputStream extends DeflaterOutputStream { _crc32.reset(); _writtenSize = 0; _headerWritten = false; + _footerWritten = false; } private static final byte[] HEADER = new byte[] { @@ -61,6 +63,7 @@ public class ResettableGZIPOutputStream extends DeflaterOutputStream { } private void writeFooter() throws IOException { + if (_footerWritten) return; // damn RFC writing their bytes backwards... long crcVal = _crc32.getValue(); out.write((int)(crcVal & 0xFF)); @@ -83,6 +86,16 @@ public class ResettableGZIPOutputStream extends DeflaterOutputStream { System.out.print( Long.toHexString((int)((sizeVal >>> 24) & 0xFF))); System.out.println(); } + _footerWritten = true; + } + + /** + * Calls super.close(). May not be reused after this. + * @since 0.9.40 + */ + public void destroy() throws IOException { + def.end(); + super.close(); } @Override @@ -90,6 +103,7 @@ public class ResettableGZIPOutputStream extends DeflaterOutputStream { finish(); super.close(); } + @Override public void finish() throws IOException { ensureHeaderIsWritten(); @@ -104,10 +118,12 @@ public class ResettableGZIPOutputStream extends DeflaterOutputStream { _writtenSize++; super.write(b); } + @Override public void write(byte buf[]) throws IOException { write(buf, 0, buf.length); } + @Override public void write(byte buf[], int off, int len) throws IOException { ensureHeaderIsWritten(); diff --git a/core/java/src/net/i2p/util/ReusableGZIPInputStream.java b/core/java/src/net/i2p/util/ReusableGZIPInputStream.java index 1c16bea2da..e8359dca4d 100644 --- a/core/java/src/net/i2p/util/ReusableGZIPInputStream.java +++ b/core/java/src/net/i2p/util/ReusableGZIPInputStream.java @@ -1,5 +1,6 @@ package net.i2p.util; +import java.io.IOException; import java.util.concurrent.LinkedBlockingQueue; /** @@ -32,13 +33,21 @@ public class ReusableGZIPInputStream extends ResettableGZIPInputStream { } return rv; } + /** * Release an instance back into the cache (this will reset the * state) */ public static void release(ReusableGZIPInputStream released) { - if (ENABLE_CACHING) - _available.offer(released); + boolean cached; + if (ENABLE_CACHING) { + cached = _available.offer(released); + } else { + cached = false; + } + if (!cached) { + try { released.destroy(); } catch (IOException ioe) {} + } } private ReusableGZIPInputStream() { super(); } diff --git a/core/java/src/net/i2p/util/ReusableGZIPOutputStream.java b/core/java/src/net/i2p/util/ReusableGZIPOutputStream.java index 9e3da53ec6..c36280b0ef 100644 --- a/core/java/src/net/i2p/util/ReusableGZIPOutputStream.java +++ b/core/java/src/net/i2p/util/ReusableGZIPOutputStream.java @@ -2,6 +2,7 @@ package net.i2p.util; //import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.zip.Deflater; import java.util.concurrent.LinkedBlockingQueue; @@ -50,9 +51,16 @@ public class ReusableGZIPOutputStream extends ResettableGZIPOutputStream { * state) */ public static void release(ReusableGZIPOutputStream out) { - out.reset(); - if (ENABLE_CACHING) - _available.offer(out); + boolean cached; + if (ENABLE_CACHING) { + out.reset(); + cached = _available.offer(out); + } else { + cached = false; + } + if (!cached) { + try { out.destroy(); } catch (IOException ioe) {} + } } private final ByteArrayOutputStream _buffer;