Bug 42713 - CBZip2OutputStream#finish method like in java.util.zip.GZIPOutputStream
Summary: CBZip2OutputStream#finish method like in java.util.zip.GZIPOutputStream
Status: RESOLVED FIXED
Alias: None
Product: Ant
Classification: Unclassified
Component: Other (show other bugs)
Version: 1.7.0
Hardware: All All
: P2 enhancement with 1 vote (vote)
Target Milestone: 1.8.0
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-06-21 03:51 UTC by Stefan Liebig
Modified: 2009-02-06 08:29 UTC (History)
1 user (show)



Attachments
Verifies/specifies the semantics of finish and close (5.73 KB, text/plain)
2007-06-22 02:11 UTC, Stefan Liebig
Details
Verifies/specifies the semantics of finish and close (6.10 KB, text/plain)
2007-10-17 22:13 UTC, Stefan Liebig
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Liebig 2007-06-21 03:51:07 UTC
The finish() method should finish writing compressed data to the output stream
without closing the underlying stream. With this method it is possible to apply
multiple filters in succession to the same output stream.
Comment 1 Stefan Liebig 2007-06-22 02:11:39 UTC
Created attachment 20388 [details]
Verifies/specifies the semantics of finish and close
Comment 2 Stefan Liebig 2007-06-22 02:12:05 UTC
Proposed patch:
 - finish added
 - close and finalize changed
------------------------------------------------------------------------------
	/**
	 * Finishes compressing to the underlying stream without closing it,
	 * so that multiple compressors can write subsequently to the same
	 * output stream.
	 *  
	 * @throws IOException
	 */
	public void finish() throws IOException {
		OutputStream outShadow = this.out;
		if ( outShadow != null && this.data != null ) {
			try {
				if ( this.runLength > 0 ) {
					writeRun();
				}
				this.currentChar = -1;
				endBlock();
				endCompression();
				//				outShadow.close();
			} finally {
				//				this.out = null;
				this.data = null;
			}
		}
	}

	/**
	 * Overriden to close the stream.
	 */
	protected void finalize() throws Throwable {
		if ( this.data != null ) {
			close();
			super.finalize();
		}
	}

	public void close() throws IOException {
		finish();
		OutputStream outShadow = this.out;
		if ( outShadow != null ) {
			try {
				outShadow.close();
			} finally {
				this.out = null;
			}
		}

		//		OutputStream outShadow = this.out;
		//		if ( outShadow != null ) {
		//			try {
		//				if ( this.runLength > 0 ) {
		//					writeRun();
		//				}
		//				this.currentChar = -1;
		//				endBlock();
		//				endCompression();
		//				outShadow.close();
		//			} finally {
		//				this.out = null;
		//				this.data = null;
		//			}
		//		}
	}
Comment 3 Stefan Liebig 2007-10-17 22:13:55 UTC
Created attachment 21001 [details]
Verifies/specifies the semantics of finish and close

Now contains Apache License 2.0
Comment 4 Darin Swanson 2007-11-12 09:14:04 UTC
This is request that would allow the Eclipse provisioning to make direct use of
the Apache Ant support without having to patch the CBZip2OutputStream.
Please see https://bugs.eclipse.org/bugs/show_bug.cgi?id=208996

Can some please review and consider this patch?
Comment 5 Peter Reilly 2007-11-12 13:06:25 UTC
The patch is against a ant 1.7.0 version of
cbzip2outputstream. This have been replaced
with a version from ant 1.6.5 as the ant 1.7.0
outstream produces corrupt bz2 files for some
inputs (ouch!).

The intent of the patch is fine, - although
I would like ZipOutputStream and CBZip2OutputStream
to have the same semantics for finish, close and finalize(!).
Comment 6 Stefan Liebig 2007-11-12 22:33:31 UTC
Having the same semantics as ZipOutputStream means that finalize() would not be
overridden? That would be ok for me. Important for us is the semantics of
finish() which ´finishes´ the compression but does not close the underlying
output stream.
Comment 7 Stefan Liebig 2007-11-13 00:40:01 UTC
Is there a bug report for this faultily behavior of the 1.7.0 version?
I modified the head version of bzip2 such that is supports the finish()
semantics. But one of my unit tests (already attached here) does fail. This
failure seems to be known
(http://issues.apache.org/bugzilla/show_bug.cgi?id=32200) and fixed (?).
Comment 8 Peter Reilly 2007-11-13 01:05:36 UTC
The buggy behavior is described in 
http://issues.apache.org/bugzilla/show_bug.cgi?id=41596

The best place to look for these is in WHATSNEW.

I do not know about 
http://issues.apache.org/bugzilla/show_bug.cgi?id=32200
but I assume that the rolled back code retriggered it.

Peter
Comment 9 Stefan Liebig 2007-11-13 05:02:46 UTC
I tried to manually apply the patch from
http://issues.apache.org/bugzilla/show_bug.cgi?id=32200 to the head version of
bzip2. This causes BZip2OutputStream to no longer fail when nothing is written
to it, but the resulting compressed date fails to decompress with BZip2InputStream.
The failure in Bzip2OS (no writes, just close) is caused by the field last = -1.
This leads to division by zero after adding 1 in method mainSort():
		for (i = 0; i < NUM_OVERSHOOT_BYTES; i++) {
			block[last + i + 2] = block[(i % (last + 1)) + 1];
		}
The patch now catches this case (last < 0) and sets than last = 0. But this case
(last == 0) is also the case when you write just exactly one byte to the
Bzip2OS. I guess thats why Bzip2IS fails with reading the result of an ´empty
compressed´ Bzip2OS.

Comment 10 Torsten Curdt 2009-01-12 03:35:23 UTC
https://issues.apache.org/jira/browse/SANDBOX-194
Comment 11 Stefan Bodewig 2009-02-06 08:27:30 UTC
merged commons-compress finish method in svn revision 741608
Comment 12 Stefan Bodewig 2009-02-06 08:29:55 UTC
oops, svn revision 741618 it is.