This is the mail archive of the
cygwin-apps
mailing list for the Cygwin project.
[PATCH 5/6] Handle bzip2 multi-stream files
- From: Jon TURNEY <jon dot turney at dronecode dot org dot uk>
- To: cygwin-apps at cygwin dot com
- Cc: Jon TURNEY <jon dot turney at dronecode dot org dot uk>
- Date: Fri, 8 Apr 2011 15:43:51 +0100
- Subject: [PATCH 5/6] Handle bzip2 multi-stream files
- References: <4D9492BD.6020103@redhat.com> <1302273832-432-1-git-send-email-jon.turney@dronecode.org.uk>
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