123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- /*
- * CCompressedStream.h, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #pragma once
- #include "CInputStream.h"
- struct z_stream_s;
- VCMI_LIB_NAMESPACE_BEGIN
- class DecompressionException : public std::runtime_error
- {
- public:
- using runtime_error::runtime_error;
- };
- /// Abstract class that provides buffer for one-directional input streams (e.g. compressed data)
- /// Used for zip archives support and in .lod deflate compression
- class CBufferedStream : public CInputStream
- {
- public:
- CBufferedStream();
- /**
- * Reads n bytes from the stream into the data buffer.
- *
- * @param data A pointer to the destination data array.
- * @param size The number of bytes to read.
- * @return the number of bytes read actually.
- *
- * @throws std::runtime_error if the file decompression was not successful
- */
- si64 read(ui8 * data, si64 size) override;
- /**
- * Seeks the internal read pointer to the specified position.
- * This will cause decompressing data till this position is found
- *
- * @param position The read position from the beginning.
- * @return the position actually moved to, -1 on error.
- */
- si64 seek(si64 position) override;
- /**
- * Gets the current read position in the stream.
- *
- * @return the read position.
- */
- si64 tell() override;
- /**
- * Skips delta numbers of bytes.
- *
- * @param delta The count of bytes to skip.
- * @return the count of bytes skipped actually.
- */
- si64 skip(si64 delta) override;
- /**
- * Gets the length in bytes of the stream.
- * Causes complete data decompression
- *
- * @return the length in bytes of the stream.
- */
- si64 getSize() override;
- protected:
- /**
- * @brief virtual method to get more data into the buffer
- * @return amount of bytes actually read, non-positive values are considered to be end-of-file mark
- */
- virtual si64 readMore(ui8 * data, si64 size) = 0;
- /// resets all internal state
- void reset();
- private:
- /// ensures that buffer contains at lest size of bytes. Calls readMore() to fill remaining part
- void ensureSize(si64 size);
- /** buffer with already decompressed data */
- std::vector<ui8> buffer;
- /** Current read position */
- si64 position;
- bool endOfFileReached;
- };
- /**
- * A class which provides method definitions for reading a gzip-compressed file
- * This class implements lazy loading - data will be decompressed (and cached) only by request
- */
- class DLL_LINKAGE CCompressedStream : public CBufferedStream
- {
- public:
- /**
- * C-tor.
- *
- * @param stream - stream with compressed data
- * @param gzip - this is gzipp'ed file e.g. campaign or maps, false for files in .lod
- * @param decompressedSize - optional parameter to hint size of decompressed data
- */
- CCompressedStream(std::unique_ptr<CInputStream> stream, bool gzip, size_t decompressedSize=0);
- ~CCompressedStream();
- /**
- * Prepare stream for decompression of next block (e.g. next part of h3c)
- * Applicable only for streams that contain multiple concatenated compressed data
- *
- * @return false if next block was not found, true othervice
- */
- bool getNextBlock();
- private:
- /**
- * Decompresses data to ensure that buffer has newSize bytes or end of stream was reached
- */
- si64 readMore(ui8 * data, si64 size) override;
- /** The file stream with compressed data. */
- std::unique_ptr<CInputStream> gzipStream;
- /** buffer with not yet decompressed data*/
- std::vector<ui8> compressedBuffer;
- /** struct with current zlib inflate state */
- std::unique_ptr<z_stream_s> inflateState;
- enum EState
- {
- ERROR_OCCURRED,
- INITIALIZED,
- IN_PROGRESS,
- STREAM_END,
- FINISHED
- };
- };
- VCMI_LIB_NAMESPACE_END
|