org.bolet.jgz
Class ZlibInputStream

java.lang.Object
  extended by java.io.InputStream
      extended by org.bolet.jgz.ZlibInputStream
All Implemented Interfaces:
java.io.Closeable

public class ZlibInputStream
extends java.io.InputStream

This class implements a decoder stream for a compressed data stream in zlib format (RFC 1950).

Such a stream is self-terminated; read() requests will return -1 if the logical data end has been reached, regardless of the status of the underlying stream, which may contain more data. Zlib streams have an internal 32-bit checksum, which this implementation verifies when the stream logical end is reached (a read attempt beyond the end is enough to trigger this verification; calling close() also works).

Zlib streams may use a dictionary, which is a bunch of uncompressed data that the compressor may use for backward references, as if it has been compressed and transmitted beforehand. The checksum is not computed over the dictionary. However, for indexing purposes, the checksum of the dictionary is provided in the stream. Whether a dictionary must be used or not is indicated in the stream. This class does not check that a dictionary is indeed provided as requested. It does not check either whether the provided dictionary matches the checksum which is indicated in the stream header.

The stream may be initialized with the partial flag set; in that mode, read() requests mark a stop at the end of each deflate block. More precisely, read(byte[]) and read(byte[],int,int) normally process input data until the logical stream end or the output buffer size, whichever comes first; in partial mode, these functions will return bytes from only one deflate block at most. This allows the calling application to implement stateful interruptions, as is required for some streaming protocols (e.g. SSH). A consequence is that read(byte[]) and read(byte[],int,int) may return 0, if the next block happens to be empty (warning: this is in violation of the InputStream API).


Field Summary
static int DEFLATE
          Compression method: the "deflate" algorithm (RFC 1951).
 
Constructor Summary
ZlibInputStream(java.io.InputStream sub)
          Create the stream.
ZlibInputStream(java.io.InputStream sub, boolean partial)
          Create the stream.
 
Method Summary
 void close()
          This close() method checks that the logical end-of-stream has been reached; the checksum is verified if this has not already been done.
 int getCompressionInfo()
          Get the compression information.
 int getCompressionLevel()
          Get the compression level.
 int getCompressionMethod()
          Get the compression method (normally DEFLATE).
 int getDictionaryId()
          Get the dictionary identifier; if none was provided, then 0 is returned (but a valid dictionary could also use the identifier value of 0; use hasDictionary() to know if a dictionary ID was supplied in the stream).
 boolean hasDictionary()
          Tell whether a dictionary was used by the compressor.
 void processDictionary(byte[] dict)
          Process a dictionary: the buffer contents are used as dictionary.
 void processDictionary(byte[] dict, int off, int len)
          Process a dictionary: the buffer contents are used as dictionary.
 void processDictionary(java.io.InputStream dict)
          Process a dictionary: the stream contents are used as dictionary.
 int read()
           
 int read(byte[] buf)
           
 int read(byte[] buf, int off, int len)
           
 void setRawStream(java.io.InputStream sub)
          Change the raw stream used to get compressed data bytes.
 
Methods inherited from class java.io.InputStream
available, mark, markSupported, reset, skip
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFLATE

public static final int DEFLATE
Compression method: the "deflate" algorithm (RFC 1951).

See Also:
Constant Field Values
Constructor Detail

ZlibInputStream

public ZlibInputStream(java.io.InputStream sub)
                throws java.io.IOException
Create the stream. The zlib header is immediately read and decoded. This constructor is equivalent to the two-parameter constructor with the partial parameter set to false.

Parameters:
sub - the underlying input stream
Throws:
java.io.IOException - on I/O or format error

ZlibInputStream

public ZlibInputStream(java.io.InputStream sub,
                       boolean partial)
                throws java.io.IOException
Create the stream. The zlib header is immediately read and decoded. Note: if partial mode is enabled, then the read() methods may return 0 (although some input data will be consumed in the process).

Parameters:
sub - the underlying input stream
partial - true to use partial mode
Throws:
java.io.IOException - on I/O or format error
Method Detail

getCompressionMethod

public int getCompressionMethod()
Get the compression method (normally DEFLATE).

Returns:
the compression method

getCompressionInfo

public int getCompressionInfo()
Get the compression information. This is a 4-bit value whose meaning depends on the compression method. For the "deflate" method, if that value is n, then the backward sequence references may reach up to 2^(n+8) previously uncompressed bytes; the maximum standard value for n is then 7 (which implies a 32 kB window).

Returns:
the compression information

getCompressionLevel

public int getCompressionLevel()
Get the compression level. This is a two-bit value which qualifies the effort deployed by the compressor. It has no strictly defined semantics and is ignored by this implementation.

Returns:
the compression level

hasDictionary

public boolean hasDictionary()
Tell whether a dictionary was used by the compressor. If this method returns true, then the same dictionary must be input; the dictionary identifier can be retrieved with the getDictionaryId() method.

Returns:
true for a dictionary

getDictionaryId

public int getDictionaryId()
Get the dictionary identifier; if none was provided, then 0 is returned (but a valid dictionary could also use the identifier value of 0; use hasDictionary() to know if a dictionary ID was supplied in the stream).

Returns:
the dictionary identifier

processDictionary

public void processDictionary(java.io.InputStream dict)
                       throws java.io.IOException
Process a dictionary: the stream contents are used as dictionary.

Parameters:
dict - the dictionary stream
Throws:
java.io.IOException - on I/O error with dict

processDictionary

public void processDictionary(byte[] dict)
Process a dictionary: the buffer contents are used as dictionary.

Parameters:
dict - the dictionary

processDictionary

public void processDictionary(byte[] dict,
                              int off,
                              int len)
Process a dictionary: the buffer contents are used as dictionary.

Parameters:
dict - the dictionary
off - the dictionary offset
len - the dictionary length

setRawStream

public void setRawStream(java.io.InputStream sub)
Change the raw stream used to get compressed data bytes. The state is not changed.

Parameters:
sub - the new input stream

close

public void close()
           throws java.io.IOException
This close() method checks that the logical end-of-stream has been reached; the checksum is verified if this has not already been done. Moreover, the underlying stream is also closed.

Specified by:
close in interface java.io.Closeable
Overrides:
close in class java.io.InputStream
Throws:
java.io.IOException
See Also:
InputStream

read

public int read()
         throws java.io.IOException
Specified by:
read in class java.io.InputStream
Throws:
java.io.IOException
See Also:
InputStream

read

public int read(byte[] buf)
         throws java.io.IOException
Overrides:
read in class java.io.InputStream
Throws:
java.io.IOException
See Also:
InputStream

read

public int read(byte[] buf,
                int off,
                int len)
         throws java.io.IOException
Overrides:
read in class java.io.InputStream
Throws:
java.io.IOException
See Also:
InputStream