| 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_BEGINclass 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 compressionclass 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 compresed 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 */	z_stream_s * inflateState;	enum EState	{		ERROR_OCCURED,		INITIALIZED,		IN_PROGRESS,		STREAM_END,		FINISHED	};};VCMI_LIB_NAMESPACE_END
 |