/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _DECAF_UTI_ZIP_INFLATER_H_ #define _DECAF_UTI_ZIP_INFLATER_H_ #include #include #include #include #include #include #include namespace decaf { namespace util { namespace zip { class InflaterData; /** * 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 InflaterInputStream and its descendants. *

* The typical usage of a Inflater outside this package consists of a specific * call to one of its constructors before being passed to an instance of * InflaterInputStream. * * @see InflaterInputStream * @see Deflater * * @since 1.0 */ class DECAF_API Inflater { private: InflaterData* data; private: Inflater( const Inflater& ); Inflater& operator=( const Inflater& ); public: /** * Creates a new decompressor. This constructor defaults the inflater to use the ZLIB * header and checksum fields. */ Inflater(); /** * Creates a new decompressor. If the parameter 'nowrap' is true then the ZLIB header * and checksum fields will not be used. This provides compatibility with the compression * format used by both GZIP and PKZIP. * * Note: When using the 'nowrap' option it is also necessary to provide an extra "dummy" * byte as input. This is required by the ZLIB native library in order to support * certain optimizations. */ Inflater( bool nowrap ); virtual ~Inflater(); /** * Sets input data for decompression. This should be called whenever needsInput() returns * true indicating that more input data is required. * * @param buffer * The Buffer to read in for decompression. * @param size * The size of the buffer passed in. * @param offset * The position in the Buffer to start reading from. * @param length * The number of bytes to read from the input buffer. * * @throws NullPointerException if buffer is NULL. * @throws IndexOutOfBoundsException if the offset + length > size of the buffer. * @throws IllegalStateException if in the end state. */ void setInput( const unsigned char* buffer, int size, int offset, int length ); /** * Sets input data for decompression. This should be called whenever needsInput() returns * true indicating that more input data is required. * * @param buffer * The Buffer to read in for decompression. * @param offset * The position in the Buffer to start reading from. * @param length * The number of bytes to read from the input buffer. * * @throws IndexOutOfBoundsException if the offset + length > size of the buffer. * @throws IllegalStateException if in the end state. */ void setInput( const std::vector& buffer, int offset, int length ); /** * Sets input data for decompression. This should be called whenever needsInput() returns * true indicating that more input data is required. * * @param buffer * The Buffer to read in for decompression. * * @throws IllegalStateException if in the end state. */ void setInput( const std::vector& buffer ); /** * Returns the total number of bytes remaining in the input buffer. This can be used to * find out what bytes still remain in the input buffer after decompression has finished. * * @returns the total number of bytes remaining in the input buffer */ int getRemaining() const; /** * Sets the preset dictionary to the given array of bytes. Should be called when inflate() * returns 0 and needsDictionary() returns true indicating that a preset dictionary is * required. The method getAdler() can be used to get the Adler-32 value of the dictionary * needed. * * @param buffer * The Buffer to read in for decompression. * @param size * The size of the buffer passed in. * @param offset * The position in the Buffer to start reading from. * @param length * The number of bytes to read from the input buffer. * * @throws NullPointerException if buffer is NULL. * @throws IndexOutOfBoundsException if the offset + length > size of the buffer. * @throws IllegalStateException if in the end state. * @throws IllegalArgumentException if the given dictionary doesn't match thre required * dictionaries checksum value. */ void setDictionary( const unsigned char* buffer, int size, int offset, int length ); /** * Sets the preset dictionary to the given array of bytes. Should be called when inflate() * returns 0 and needsDictionary() returns true indicating that a preset dictionary is * required. The method getAdler() can be used to get the Adler-32 value of the dictionary * needed. * * @param buffer * The Buffer to read in for decompression. * @param offset * The position in the Buffer to start reading from. * @param length * The number of bytes to read from the input buffer. * * @throws IndexOutOfBoundsException if the offset + length > size of the buffer. * @throws IllegalStateException if in the end state. * @throws IllegalArgumentException if the given dictionary doesn't match thre required * dictionaries checksum value. */ void setDictionary( const std::vector& buffer, int offset, int length ); /** * Sets the preset dictionary to the given array of bytes. Should be called when inflate() * returns 0 and needsDictionary() returns true indicating that a preset dictionary is * required. The method getAdler() can be used to get the Adler-32 value of the dictionary * needed. * * @param buffer * The Buffer to read in for decompression. * * @throws IllegalStateException if in the end state. * @throws IllegalArgumentException if the given dictionary doesn't match the required * dictionaries checksum value. */ void setDictionary( const std::vector& buffer ); /** * @return true if the input data buffer is empty and setInput() should be called in * order to provide more input */ bool needsInput() const; /** * @returns true if a preset dictionary is needed for decompression. */ bool needsDictionary() const; /** * When called, indicates that decompression should end with the current contents of * the input buffer. */ void finish(); /** * @return true if the end of the compressed data output stream has been reached. */ bool finished() const; /** * Uncompresses bytes into specified buffer. Returns actual number of bytes uncompressed. * A return value of 0 indicates that needsInput() or needsDictionary() should be called * in order to determine if more input data or a preset dictionary is required. In the * latter case, getAdler() can be used to get the Adler-32 value of the dictionary required. * * @param buffer * The Buffer to write the compressed data to. * @param size * The size of the buffer passed in. * @param offset * The position in the Buffer to start writing at. * @param length * The maximum number of byte of data to write. * * @throws NullPointerException if buffer is NULL. * @throws IllegalStateException if in the end state. * @throws IndexOutOfBoundsException if the offset + length > size of the buffer. * @throws DataFormatException if the compressed data format is invalid. */ int inflate( unsigned char* buffer, int size, int offset, int length ); /** * Uncompresses bytes into specified buffer. Returns actual number of bytes uncompressed. * A return value of 0 indicates that needsInput() or needsDictionary() should be called * in order to determine if more input data or a preset dictionary is required. In the * latter case, getAdler() can be used to get the Adler-32 value of the dictionary required. * * @param buffer * The Buffer to write the compressed data to. * @param offset * The position in the Buffer to start writing at. * @param length * The maximum number of byte of data to write. * * @throws IllegalStateException if in the end state. * @throws IndexOutOfBoundsException if the offset + length > size of the buffer. * @throws DataFormatException if the compressed data format is invalid. */ int inflate( std::vector& buffer, int offset, int length ); /** * Uncompresses bytes into specified buffer. Returns actual number of bytes uncompressed. * A return value of 0 indicates that needsInput() or needsDictionary() should be called * in order to determine if more input data or a preset dictionary is required. In the * latter case, getAdler() can be used to get the Adler-32 value of the dictionary required. * * @param buffer * The Buffer to write the compressed data to. * * @throws IllegalStateException if in the end state. * @throws DataFormatException if the compressed data format is invalid. */ int inflate( std::vector& buffer ); /** * @returns the ADLER-32 value of the uncompressed data. * * @throws IllegalStateException if in the end state. */ long long getAdler() const; /** * @returns the total number of compressed bytes input so far. * * @throws IllegalStateException if in the end state. */ long long getBytesRead() const; /** * @return the total number of decompressed bytes output so far. * * @throws IllegalStateException if in the end state. */ long long getBytesWritten() const; /** * Resets deflater so that a new set of input data can be processed. Keeps current decompression * level and strategy settings. * * @throws IllegalStateException if in the end state. */ void reset(); /** * Closes the decompressor and discards any unprocessed input. This method should be called * when the decompressor is no longer being used, but will also be called automatically by the * destructor. Once this method is called, the behavior of the Inflater object is undefined. */ void end(); }; }}} #endif /* _DECAF_UTI_ZIP_INFLATER_H_ */