ZLibInputStream.java

 1package eu.siacs.conversations.utils.zlib;
 2
 3import java.io.IOException;
 4import java.io.InputStream;
 5import java.util.zip.Inflater;
 6import java.util.zip.InflaterInputStream;
 7
 8/**
 9 * ZLibInputStream is a zlib and input stream compatible version of an
10 * InflaterInputStream. This class solves the incompatibility between
11 * {@link InputStream#available()} and {@link InflaterInputStream#available()}.
12 */
13public class ZLibInputStream extends InflaterInputStream {
14
15    /**
16     * Construct a ZLibInputStream, reading data from the underlying stream.
17     *
18     * @param is The {@code InputStream} to read data from.
19     * @throws IOException If an {@code IOException} occurs.
20     */
21    public ZLibInputStream(InputStream is) throws IOException {
22        super(is, new Inflater(), 512);
23    }
24
25    /**
26     * Provide a more InputStream compatible version of available.
27     * A return value of 1 means that it is likly to read one byte without
28     * blocking, 0 means that the system is known to block for more input.
29     *
30     * @return 0 if no data is available, 1 otherwise
31     * @throws IOException
32     */
33    @Override
34    public int available() throws IOException {
35        /* This is one of the funny code blocks.
36         * InflaterInputStream.available violates the contract of
37         * InputStream.available, which breaks kXML2.
38         *
39         * I'm not sure who's to blame, oracle/sun for a broken api or the
40         * google guys for mixing a sun bug with a xml reader that can't handle
41         * it....
42         *
43         * Anyway, this simple if breaks suns distorted reality, but helps
44         * to use the api as intended.
45         */
46        if (inf.needsInput()) {
47            return 0;
48        }
49        return super.available();
50    }
51
52}