FileDocCategorySizeDatePackage
Inflater.javaAPI DocAndroid 1.5 API15612Wed May 06 22:41:02 BST 2009java.util.zip

Inflater

public class Inflater extends Object
This class uncompresses data that was compressed using the DEFLATE algorithm (see specification).

Basically this class is part of the API to the stream based ZLIB compression library and is used as such by {@code InflaterInputStream} and its descendants.

The typical usage of a {@code Inflater} outside this package consists of a specific call to one of its constructors before being passed to an instance of {@code InflaterInputStream}.

see
InflaterInputStream
see
Deflater
since
Android 1.0

Fields Summary
private boolean
finished
private boolean
needsDictionary
private long
streamHandle
int
inRead
int
inLength
private static final byte
MAGIC_NUMBER
private boolean
gotFirstByte
private boolean
pass_magic_number_check
Constructors Summary
public Inflater()
This constructor creates an inflater that expects a header from the input stream. Use {@code Inflater(boolean)} if the input comes without a ZLIB header.

since
Android 1.0
since
Android 1.0

        this(false);
    
public Inflater(boolean noHeader)
This constructor allows to create an inflater that expects no header from the input stream.

param
noHeader {@code true} indicates that no ZLIB header comes with the input.
since
Android 1.0

        streamHandle = createStream(noHeader);
    
Methods Summary
private native longcreateStream(boolean noHeader1)

public synchronized voidend()
Release any resources associated with this {@code Inflater}. Any unused input/output is discarded. This is also called by the finalize method.

since
Android 1.0

    
                                  
        
        if (streamHandle != -1) {
            endImpl(streamHandle);
            inRead = 0;
            inLength = 0;
            streamHandle = -1;
        }
    
private native synchronized voidendImpl(long handle)

protected voidfinalize()

        end();
    
public synchronized booleanfinished()
Indicates if the {@code Inflater} has inflated the entire deflated stream. If deflated bytes remain and {@code needsInput()} returns {@code true} this method will return {@code false}. This method should be called after all deflated input is supplied to the {@code Inflater}.

return
{@code true} if all input has been inflated, {@code false} otherwise.
since
Android 1.0

        return finished;
    
public synchronized intgetAdler()
Returns the Adler32 checksum of either all bytes inflated, or the checksum of the preset dictionary if one has been supplied.

return
The Adler32 checksum associated with this {@code Inflater}.
since
Android 1.0 .

        if (streamHandle == -1) {
            throw new IllegalStateException();
        }
        return getAdlerImpl(streamHandle);
    
private native synchronized intgetAdlerImpl(long handle)

public synchronized longgetBytesRead()
Returns the total number of bytes read by the {@code Inflater}. This method performs the same as {@code getTotalIn()} except that it returns a {@code long} value instead of an integer.

return
the total number of bytes read.
since
Android 1.0

        // Throw NPE here
        if (streamHandle == -1) {
            throw new NullPointerException();
        }
        return getTotalInImpl(streamHandle);
    
public synchronized longgetBytesWritten()
Returns a the total number of bytes read by the {@code Inflater}. This method performs the same as {@code getTotalOut} except it returns a {@code long} value instead of an integer.

return
the total bytes written to the output buffer.
since
Android 1.0

        // Throw NPE here
        if (streamHandle == -1) {
            throw new NullPointerException();
        }
        return getTotalOutImpl(streamHandle);
    
public synchronized intgetRemaining()
Returns the number of bytes of current input remaining to be read by the inflater.

return
the number of bytes of unread input.
since
Android 1.0

        return inLength - inRead;
    
public synchronized intgetTotalIn()
Returns total number of bytes of input read by the {@code Inflater}. The result value is limited by {@code Integer.MAX_VALUE}.

return
the total number of bytes read.
since
Android 1.0

        if (streamHandle == -1) {
            throw new IllegalStateException();
        }
        long totalIn = getTotalInImpl(streamHandle);
        return (totalIn <= Integer.MAX_VALUE ? (int) totalIn
                : Integer.MAX_VALUE);
    
private native synchronized longgetTotalInImpl(long handle)

public synchronized intgetTotalOut()
Returns total number of bytes written to the output buffer by the {@code Inflater}. The result value is limited by {@code Integer.MAX_VALUE}.

return
the total bytes of output data written.
since
Android 1.0

        if (streamHandle == -1) {
            throw new IllegalStateException();
        }
        long totalOut = getTotalOutImpl(streamHandle);
        return (totalOut <= Integer.MAX_VALUE ? (int) totalOut
                : Integer.MAX_VALUE);
    
private native synchronized longgetTotalOutImpl(long handle)

public intinflate(byte[] buf)
Inflates bytes from current input and stores them in {@code buf}.

param
buf the buffer where decompressed data bytes are written.
return
the number of bytes inflated.
throws
DataFormatException if the underlying stream is corrupted or was not compressed using a {@code Deflater}.
since
Android 1.0

        return inflate(buf, 0, buf.length);
    
public synchronized intinflate(byte[] buf, int off, int nbytes)
Inflates up to n bytes from the current input and stores them in {@code buf} starting at {@code off}.

param
buf the buffer to write inflated bytes to.
param
off the offset in buffer where to start writing decompressed data.
param
nbytes the number of inflated bytes to write to {@code buf}.
throws
DataFormatException if the underlying stream is corrupted or was not compressed using a {@code Deflater}.
return
the number of bytes inflated.

        // avoid int overflow, check null buf
        if (off <= buf.length && nbytes >= 0 && off >= 0
                && buf.length - off >= nbytes) {
            if (nbytes == 0)
                return 0;

            if (streamHandle == -1) {
                throw new IllegalStateException();
            }
            
            if (!pass_magic_number_check) {
                throw new DataFormatException();
            }

            if (needsInput()) {
                return 0;
            }
            
            boolean neededDict = needsDictionary;
            needsDictionary = false;
            int result = inflateImpl(buf, off, nbytes, streamHandle);
            if (needsDictionary && neededDict) {
                throw new DataFormatException(Messages.getString("archive.27")); //$NON-NLS-1$
            }
            return result;
        }
        throw new ArrayIndexOutOfBoundsException();
    
private native synchronized intinflateImpl(byte[] buf, int off, int nbytes, long handle)

public synchronized booleanneedsDictionary()
Indicates whether the input bytes were compressed with a preset dictionary. This method should be called prior to {@code inflate()} to determine whether a dictionary is required. If so {@code setDictionary()} should be called with the appropriate dictionary prior to calling {@code inflate()}.

return
{@code true} if a preset dictionary is required for inflation.
see
#setDictionary(byte[])
see
#setDictionary(byte[], int, int)
since
Android 1.0

        return needsDictionary;
    
public synchronized booleanneedsInput()
Indicates that input has to be passed to the inflater.

return
{@code true} if {@code setInput} has to be called before inflation can proceed.
see
#setInput(byte[])
since
Android 1.0

        return inRead == inLength;
    
private static native voidoneTimeInitialization()

public synchronized voidreset()
Resets the {@code Inflater}. Should be called prior to inflating a new set of data.

since
Android 1.0

        if (streamHandle == -1) {
            throw new NullPointerException();
        }
        finished = false;
        needsDictionary = false;
        inLength = inRead = 0;
        resetImpl(streamHandle);
    
private native synchronized voidresetImpl(long handle)

public synchronized voidsetDictionary(byte[] buf)
Sets the preset dictionary to be used for inflation to {@code buf}. {@code needsDictionary()} can be called to determine whether the current input was deflated using a preset dictionary.

param
buf The buffer containing the dictionary bytes.
see
#needsDictionary
since
Android 1.0

        setDictionary(buf, 0, buf.length);
    
public synchronized voidsetDictionary(byte[] buf, int off, int nbytes)
Like {@code setDictionary(byte[])}, allowing to define a specific region inside {@code buf} to be used as a dictionary.

param
buf the buffer containing the dictionary data bytes.
param
off the offset of the data.
param
nbytes the length of the data.
see
#needsDictionary
since
Android 1.0

        if (streamHandle == -1) {
            throw new IllegalStateException();
        }
        // avoid int overflow, check null buf
        if (off <= buf.length && nbytes >= 0 && off >= 0
                && buf.length - off >= nbytes) {
            setDictionaryImpl(buf, off, nbytes, streamHandle);
        } else {
            throw new ArrayIndexOutOfBoundsException();
        }
    
private native synchronized voidsetDictionaryImpl(byte[] buf, int off, int nbytes, long handle)

synchronized intsetFileInput(java.io.FileDescriptor fd, long off, int nbytes)
Sets the current input to the region within a file starting at {@code off} and ending at {@code nbytes - 1}. This method should only be called if {@code needsInput()} returns {@code true}.

param
file the input file.
param
off the offset to read from in buffer.
param
nbytes the number of bytes to read.
see
#needsInput
since
Android 1.0

        if (streamHandle == -1) {
            throw new IllegalStateException();
        }
        inRead = 0;
        inLength = setFileInputImpl(fd, off, nbytes, streamHandle);
        return inLength;
    
private native synchronized intsetFileInputImpl(java.io.FileDescriptor fd, long off, int nbytes, long handle)

public synchronized voidsetInput(byte[] buf)
Sets the current input to to be decrompressed. This method should only be called if {@code needsInput()} returns {@code true}.

param
buf the input buffer.
see
#needsInput
since
Android 1.0

        setInput(buf, 0, buf.length);
    
public synchronized voidsetInput(byte[] buf, int off, int nbytes)
Sets the current input to the region of the input buffer starting at {@code off} and ending at {@code nbytes - 1} where data is written after decompression. This method should only be called if {@code needsInput()} returns {@code true}.

param
buf the input buffer.
param
off the offset to read from the input buffer.
param
nbytes the number of bytes to read.
see
#needsInput
since
Android 1.0

        if (streamHandle == -1) {
            throw new IllegalStateException();
        }
        // avoid int overflow, check null buf
        if (off <= buf.length && nbytes >= 0 && off >= 0
                && buf.length - off >= nbytes) {
            inRead = 0;
            inLength = nbytes;
            setInputImpl(buf, off, nbytes, streamHandle);
        } else {
            throw new ArrayIndexOutOfBoundsException();
        }
        // BEGIN android-note
        // Note:  pass_magic_number_check is set to false when setInput is
        //        called for the first time and for a single byte.
        //        Since setInput is called only by InflaterInputStream.fill
        //        with an arbitrary byte len this check seems quite useless.
        // FIXME: We should find out whether the first byte has to be the magic
        //        number in all cases and correct the check as well as place it
        //        in setFileInput accordingly.
        //        And at a first glance it doesn't look like the first byte has
        //        to be 120.
        // END android-note
        if(!gotFirstByte && nbytes>0)
        {
           pass_magic_number_check = (buf[off] == MAGIC_NUMBER || nbytes > 1);           
           gotFirstByte = true;
        }
    
private native synchronized voidsetInputImpl(byte[] buf, int off, int nbytes, long handle)