This is the mail archive of the cygwin-apps mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 5/6] Handle bzip2 multi-stream files


bzip2 compressed files are allowed to contain multiple streams of
compressed data.  So if we arrive at BZ_STREAM_END but are not at
EOF, restart the decompressor.  Decompress any data which remains
in the stream before reading any more.

Also remove write only member bufN

2011-04-08  Jon TURNEY  <jon.turney@dronecode.org.uk>

	* compress_bz.h (compress): Remove unused bufN member.
	* compress_bz.cc (read): Handle bzip2 files containing multiple
	streams

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
---
 compress_bz.cc |   35 ++++++++++++++++++++---------------
 compress_bz.h  |    1 -
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/compress_bz.cc b/compress_bz.cc
index f45f434..fb23529 100644
--- a/compress_bz.cc
+++ b/compress_bz.cc
@@ -37,7 +37,6 @@ compress_bz::compress_bz (io_stream * parent) : peeklen (0), position (0)
 
   initialisedOk = 0;
   endReached = 0;
-  bufN = 0;
   writing = 0;
   strm.bzalloc = 0;
   strm.bzfree = 0;
@@ -78,34 +77,26 @@ compress_bz::read (void *buffer, size_t len)
       else
         return tmpread;
   }
-  
+
   strm.avail_out = len;
   strm.next_out = (char *) buffer;
   int rlen = 1;
   while (1)
     {
-      if (original->error ())
-	{
-	  lasterr = original->error ();
-	  return -1;
-	}
+      int ret = BZ2_bzDecompress (&strm);
+
       if (strm.avail_in == 0 && rlen > 0)
 	{
 	  rlen = original->read (buf, 4096);
 	  if (rlen < 0)
 	    {
-	      if (original->error ())
-    		lasterr = original->error ();
-	      else
-		lasterr = rlen;
+              lasterr = original->error ();
 	      return -1;
 	    }
-	  bufN = rlen;
 	  strm.avail_in = rlen;
 	  strm.next_in = buf;
 	}
-      int
-	ret = BZ2_bzDecompress (&strm);
+
       if (ret != BZ_OK && ret != BZ_STREAM_END)
 	{
 	  lasterr = ret;
@@ -119,7 +110,21 @@ compress_bz::read (void *buffer, size_t len)
 	}
       if (ret == BZ_STREAM_END)
 	{
-	  endReached = 1;
+          /* Are we also at EOF? */
+          if (rlen == 0)
+            {
+              endReached = 1;
+            }
+          else
+            {
+              /* BZ_SSTREAM_END but not at EOF means the file contains
+                 another stream */
+              BZ2_bzDecompressEnd (&strm);
+              BZ2_bzDecompressInit (&(strm), 0, 0);
+              /* This doesn't reinitialize strm, so strm.next_in still
+                 points at strm.avail_in bytes left to decompress in buf */
+            }
+
 	  position += len - strm.avail_out;
 	  return len - strm.avail_out;
 	}
diff --git a/compress_bz.h b/compress_bz.h
index 24f68a7..39a0d5b 100644
--- a/compress_bz.h
+++ b/compress_bz.h
@@ -64,7 +64,6 @@ private:
   bz_stream strm;
   int initialisedOk;
   int endReached;
-  int bufN;
   char buf[4096];
   int writing;
   size_t position;
-- 
1.7.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]