[kaffe] InflaterOutputStream.read

Arne Woerner woerner@mediabase-gmbh.de
Wed, 14 Aug 2002 14:20:53 +0200 (CEST)


Hi!

I think InflaterInputStream.read(byte[]...) behaves a little bit funny
(in Kaffe 1.0.6 and in SUN JDK 1.1.7b, too): If you want to read many
bytes (in relation to the buffer size of the InflaterInputStream instance)
it reads sometimes nothing (Kaffe only) or not so much (both).

For further details see:
appendix A: source of the test application
appendix C: shell command that starts the test
appendix B.1: output of the original application
appendix D: modified InflaterInputStream.read(byte[]...)
appendix B.2: output of the application with modified Inflater...

I think the modified behaviour is more convenient... Although recursive calls
are not so efficient... ;-)

Maybe someone could change the interface of the Inflater class so that it
provides a skip operation... :-)

Bye
Arne

appendix A: source of class IOStest
// $Id$
// tests InflaterInputStream.read() with long lenx

import java.io.IOException;

// IOStest is not in package java.util.zip
[import java.util.zip.GZIPInputStream;]

public class IOStest {

public static void main(String[] args) {
	try {
		GZIPInputStream ios = new GZIPInputStream(System.in,10);

		byte[] bs = new byte[10000];
		System.out.println("filled "+ios.read(bs)+"bytes.");
		System.out.println("filled "+ios.read(bs)+"bytes.");
	} catch (IOException ioe) {
		ioe.printStackTrace(System.out);
	}
};

};

appendix B.1: output with "import ...GZIPInputStream"
10+0 records in
10+0 records out
10000 bytes transferred in 0.000 secs (76335878 bytes/sec)
filled 0bytes.
filled 4904bytes.

appendix B.2: output without "import ...GZIPInputStream"
10+0 records in
10+0 records out
10000 bytes transferred in 0.000 secs (78125000 bytes/sec)
DEBUG: 0
DEBUG: 4904
DEBUG: 5096
DEBUG2: 5096
DEBUG2: 10000
DEBUG2: 10000
filled 10000bytes.
filled -1bytes.

appendix C: test setting
> dd if=/dev/zero bs=1000 count=10 | gzip -9 | java IOStest

appendix D: source of my InflaterInputStream.read
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

import java.util.zip.*;

/*
 * Java core library component.
 *
 * Copyright (c) 1997, 1998
 *      Transvirtual Technologies, Inc.  All rights reserved.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file.
 */
public class InflaterInputStream
  extends FilterInputStream
{
	final private static int DEFAULT = 512;
	protected Inflater inf;
	protected byte[] buf;
	protected int len;

public InflaterInputStream(InputStream in) {
	this(in, new Inflater(), DEFAULT);
}

public InflaterInputStream(InputStream in, Inflater inf) {
	this(in, inf, DEFAULT);
}

public InflaterInputStream(InputStream in, Inflater inf, int size) {
	super(in);
	if (in == null)
	  throw new NullPointerException("in");
	if (inf == null)
	  throw new NullPointerException("inf");
	this.inf = inf;
	if (size < 1)
	  throw new IllegalArgumentException("size < 1");
	buf = new byte[size];
	len = 0;
}

protected void fill() throws IOException {
	len = super.read(buf, 0, buf.length);
}

public int read() throws IOException {
	byte[] b = new byte[1];
	int r = read(b, 0, 1);
	if (r == -1) {
		return (-1);
	}
	else {
		return ((int)b[0]);
	}
}

public int read(byte b[], int off, int lenx) throws IOException {
	if (inf.finished()) {
		return (-1);
	}
	if (inf.needsInput()) {
		fill();
		if (len == -1) {
			return (-1);
		}
		inf.setInput(buf, 0, len);
	}
	int lenr = 0;
	try {
		lenr = inf.inflate(b, off, lenx);
	}
	catch (DataFormatException _) {
		throw new IOException("bad data format");
	}
System.out.println("DEBUG: "+lenr);
	if (lenr < lenx) {
		int lenr2 = read(b,off+lenr,lenx-lenr);
		if (lenr2 == -1)
			return -1;
		lenr += lenr2;
	}
System.out.println("DEBUG2: "+lenr);
	return lenr;
}

public long skip(long n) throws IOException {
	// This is a terribly inefficient way to skip ...
	long cnt;
	byte[] b = new byte[1];

	for (cnt = 0; cnt < n; cnt++) {
		int r = read(b, 0, 1);
		if (r == -1) {
			break;
		}
	}
	return (cnt);
}

}