diff --git a/src/main/java/com/jcraft/jzlib/GZIPInputStream.java b/src/main/java/com/jcraft/jzlib/GZIPInputStream.java index d7a2518..8ca65a6 100644 --- a/src/main/java/com/jcraft/jzlib/GZIPInputStream.java +++ b/src/main/java/com/jcraft/jzlib/GZIPInputStream.java @@ -50,6 +50,25 @@ public GZIPInputStream(InputStream in, super(in, inflater, size, close_in); } + public int read(byte[] b, int off, int len) throws IOException { + int i = super.read(b, off, len); + if(i == -1){ + if(inflater.avail_in<2){ + int l = in.read(buf, 0, buf.length); + if(l>0) + inflater.setInput(buf, 0, l, true); + } + if(inflater.avail_in>2 && + ((inflater.next_in[inflater.next_in_index]&0xff) == 0x1f) && + ((inflater.next_in[inflater.next_in_index+1]&0xff) == (0x8b&0xff))){ + this.inflater.reset(); + this.eof=false; + return super.read(b, off, len); + } + } + return i; + } + /** * @deprecated use getModifiedTime() * @return long modified time. diff --git a/src/main/java/com/jcraft/jzlib/Inflater.java b/src/main/java/com/jcraft/jzlib/Inflater.java index 0fb0b09..4a0efcb 100644 --- a/src/main/java/com/jcraft/jzlib/Inflater.java +++ b/src/main/java/com/jcraft/jzlib/Inflater.java @@ -57,6 +57,10 @@ final public class Inflater extends ZStream{ static final private int Z_BUF_ERROR=-5; static final private int Z_VERSION_ERROR=-6; + private int param_w = -1; + private JZlib.WrapperType param_wrapperType = null; + private boolean param_nowrap = false; + public Inflater() { super(); init(); @@ -68,6 +72,8 @@ public Inflater(JZlib.WrapperType wrapperType) throws GZIPException { public Inflater(int w, JZlib.WrapperType wrapperType) throws GZIPException { super(); + param_w = w; + param_wrapperType = wrapperType; int ret = init(w, wrapperType); if(ret!=Z_OK) throw new GZIPException(ret+": "+msg); @@ -83,11 +89,23 @@ public Inflater(boolean nowrap) throws GZIPException { public Inflater(int w, boolean nowrap) throws GZIPException { super(); + param_w = w; + param_nowrap = nowrap; int ret = init(w, nowrap); if(ret!=Z_OK) throw new GZIPException(ret+": "+msg); } + void reset() { + finished = false; + if(param_wrapperType != null){ + init(param_w, param_wrapperType); + } + else { + init(param_w, param_nowrap); + } + } + private boolean finished = false; public int init(){ diff --git a/src/main/java/com/jcraft/jzlib/InflaterInputStream.java b/src/main/java/com/jcraft/jzlib/InflaterInputStream.java index 0420582..dceb007 100644 --- a/src/main/java/com/jcraft/jzlib/InflaterInputStream.java +++ b/src/main/java/com/jcraft/jzlib/InflaterInputStream.java @@ -36,7 +36,7 @@ public class InflaterInputStream extends FilterInputStream { private boolean closed = false; - private boolean eof = false; + protected boolean eof = false; private boolean close_in = true; diff --git a/src/test/scala/GZIPIOStreamTest.scala b/src/test/scala/GZIPIOStreamTest.scala index 9a27cff..ee07891 100644 --- a/src/test/scala/GZIPIOStreamTest.scala +++ b/src/test/scala/GZIPIOStreamTest.scala @@ -90,4 +90,27 @@ class GZIPIOStreamTest extends FlatSpec with BeforeAndAfter with ShouldMatchers csIn.getValue() should equal(csOut.getValue) } + + behavior of "GZIPInputStream" + + it can "inflate a concatenated gzip stream." in { + // echo -n "a" | gzip > data + // echo -n "b" | gzip >> data + // echo -n "c" | gzip >> data + val data = { + val baos1 = new ByteArrayOutputStream + List("a", "b", "c").map{s => + val gos = new GZIPOutputStream(baos1) + gos.write(s.getBytes); + gos.close + } + baos1.toByteArray + } + + val gis = new GZIPInputStream(new ByteArrayInputStream(data)) + val baos = new ByteArrayOutputStream() + gis -> baos + + baos.toByteArray should equal("abc".getBytes) + } }