From 16f738ecee689c6feb2acb7e4ef4d9bb4144ae7d Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Sun, 8 Jun 2008 11:04:43 +0200 Subject: Initial commit --- zip/ZipArchive/ZipCompressor.h | 485 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 zip/ZipArchive/ZipCompressor.h (limited to 'zip/ZipArchive/ZipCompressor.h') diff --git a/zip/ZipArchive/ZipCompressor.h b/zip/ZipArchive/ZipCompressor.h new file mode 100644 index 0000000..be2855d --- /dev/null +++ b/zip/ZipArchive/ZipCompressor.h @@ -0,0 +1,485 @@ +//////////////////////////////////////////////////////////////////////////////// +// This source file is part of the ZipArchive library source distribution and +// is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// For the licensing details refer to the License.txt file. +// +// Web Site: http://www.artpol-software.com +//////////////////////////////////////////////////////////////////////////////// + +/** +* \file ZipCompressor.h +* Includes the CZipCompressor class. +* +*/ + +#if !defined(ZIPARCHIVE_ZIPCOMPRESSOR_DOT_H) +#define ZIPARCHIVE_ZIPCOMPRESSOR_DOT_H + +#if _MSC_VER > 1000 + #pragma once + #pragma warning( push ) + #pragma warning (disable : 4100) // unreferenced formal parameter +#endif + +#include "ZipExport.h" +#include "ZipAutoBuffer.h" +#include "ZipFileHeader.h" +#include "ZipStorage.h" +#include "ZipCryptograph.h" +#include "ZipException.h" + +/** + A base class for compressors used in compression and decompression of data. +*/ +class ZIP_API CZipCompressor +{ +protected: + CZipStorage* m_pStorage; ///< The current storage object. + CZipAutoBuffer m_pBuffer; ///< A buffer that receives compressed data or provides data for decompression. + CZipCryptograph* m_pCryptograph; ///< Current cryptograph. + CZipFileHeader* m_pFile; ///< The file header being compressed or decompressed. + + + /** + Initializes a new instance of the CZipCompressor class. + + \param pStorage + The current storage object. + */ + CZipCompressor(CZipStorage* pStorage) + :m_pStorage(pStorage) + { + m_pCryptograph = NULL; + m_uUncomprLeft = 0; + m_uComprLeft = 0; + m_uCrc32 = 0; + } + +public: + /** + The type of a compressor. + */ + enum CompressorType + { + typeDeflate = 1, ///< Deflate compression (default in zip archives). + typeBzip2 ///< Bzip2 compression. + }; + + /** + The compression level. + */ + enum CompressionLevel + { + levelDefault = -1, ///< The default compression level (equals 6 for deflate). + levelStore = 0, ///< No compression used. Data is stored. + levelFastest = 1, ///< The fastest compression. The compression ratio is the lowest (apart from #levelStore). + levelBest = 9 ///< The highest compression ratio. It's usually the slowest. + }; + + /** + The compression method. + */ + enum CompressionMethod + { + methodStore = 0, ///< A file is stored, not compressed. + methodDeflate = 8, ///< The deflate compression method. + /** + A file is compressed using the bzip2 algorithm. + + \see + 0610231446|bzip2 + */ + methodBzip2 = 12, + /** + This value means that WinZip AES encryption is used. + The original compression method is stored in a WinZip extra field. + It is only an informational value - you cannot set it as a compression method. The ZipArchive + Library handles this value internally. + + \see + 0610201627|aes + */ + methodWinZipAes = 99 + }; + + /** + The base class for compressors options. + + \see + 0610231446|options + \see + CZipArchive::SetCompressionOptions + */ + struct ZIP_API COptions + { + + /** + Helper constants. + */ + enum Constants + { + /** + The default size of the buffer used in compression and decompression operations. + */ + cDefaultBufferSize = 2 * 65536 + }; + + COptions() + { + m_iBufferSize = cDefaultBufferSize; + } + + /** + Gets the type of the compressor to which the current options apply. + + \return + The type of the compressor. It can be one of the #CompressorType values. + */ + virtual int GetType() const = 0; + + /** + Clones the current options object. + + \return + The cloned object of the same type as the current object. + */ + virtual COptions* Clone() const = 0; + + /** + The size of the buffer used in compression and decompression operations. + By default it is set to to #cDefaultBufferSize. For the optimal performance of the + deflate algorithm it should be set at least to 128kB. + + \see + CZipArchive::SetAdvanced + */ + int m_iBufferSize; + virtual ~COptions() + { + } + }; + + + /** + A dictionary used for keeping options for different types of compressors. + + \see + CZipArchive::SetCompressionOptions + */ + class ZIP_API COptionsMap : public CZipMap + { + public: + void Set(const COptions* pOptions); + void Remove(int iType); + COptions* Get(int iType) const; + ~COptionsMap(); + }; + + /** + Returns the value indicating whether the given compression method is supported by the ZipArchive Library. + + \param uCompressionMethod + The compression method. Can be one of the #CompressionMethod values. + + \return + \c true, if the compression method is supported, \c false otherwise. + */ + static bool IsCompressionSupported(WORD uCompressionMethod) + { + return uCompressionMethod == methodStore || uCompressionMethod == methodDeflate + ; + } + + ZIP_SIZE_TYPE m_uUncomprLeft; ///< The number of bytes left to decompress. + ZIP_SIZE_TYPE m_uComprLeft; ///< The number of bytes left to compress. + DWORD m_uCrc32; ///< The CRC32 file checksum. + + /** + Returns the value indicating, if the current #CZipCompressor object supports the given compression method. + + \param uMethod + The compression method. Can be one of the #CompressionMethod values. + + \return + \c true, if the compression method is supported; \c false otherwise. + + */ + virtual bool CanProcess(WORD uMethod) = 0; + + + /** + The method called when a new file is opened for compression. + + \param iLevel + The compression level. + + \param pFile + The file being compressed. + + \param pCryptograph + The current CZipCryptograph. Can be \c NULL, if no encryption is used. + + \see + Compress + \see + FinishCompression + */ + virtual void InitCompression(int iLevel, CZipFileHeader* pFile, CZipCryptograph* pCryptograph) + { + InitBuffer(); + m_uComprLeft = 0; + m_pFile = pFile; + m_pCryptograph = pCryptograph; + } + + /** + The method called when a new file is opened for extraction. + + \param pFile + The file being extracted. + + \param pCryptograph + The current CZipCryptograph. Can be \c NULL, if no decryption is used. + + \see + Decompress + \see + FinishDecompression + */ + virtual void InitDecompression(CZipFileHeader* pFile, CZipCryptograph* pCryptograph) + { + InitBuffer(); + m_pFile = pFile; + m_pCryptograph = pCryptograph; + + m_uComprLeft = m_pFile->GetDataSize(false, true); + m_uUncomprLeft = m_pFile->m_uUncomprSize; + m_uCrc32 = 0; + } + + /** + Compresses the given data. + + \param pBuffer + The buffer that holds the data to compress. + + \param uSize + The size of \a pBuffer. + + \see + InitCompression + \see + FinishCompression + */ + virtual void Compress(const void *pBuffer, DWORD uSize) = 0; + + /** + Decompresses the given data. + + \param pBuffer + The buffer that receives the decompressed data. + + \param uSize + The size of \a pBuffer. + + \return + The number of bytes decompressed and written to \a pBuffer. + + \note + This method should be called repeatedly until it returns 0. + + \see + InitDecompression + \see + FinishDecompression + */ + virtual DWORD Decompress(void *pBuffer, DWORD uSize) = 0; + + /** + The method called at the end of the compression process. + + \param bAfterException + Set to \c true, if an exception occurred before or to \c false otherwise. + + \see + InitCompression + \see + Compress + */ + virtual void FinishCompression(bool bAfterException){} + + /** + The method called at the end of the decompression process. + + \param bAfterException + Set to \c true, if an exception occurred before or to \c false otherwise. + + \see + InitDecompression + \see + Decompress + */ + virtual void FinishDecompression(bool bAfterException){} + + /** + Returns the current options of the compressor. + + \return + The current options for the compressor. + + \see + 0610231446|options + \see + CZipArchive::SetCompressionOptions + \see + UpdateOptions + */ + virtual const COptions* GetOptions() const + { + return NULL; + } + + /** + Updates the current options with the options stored in \a optionsMap, + if the appropriate options are present in the map. + + \param optionsMap + The map to get the new options from. + + \see + 0610231446|options + \see + GetOptions + */ + void UpdateOptions(const COptionsMap& optionsMap); + + + virtual ~CZipCompressor() + { + } + + /** + A factory method that creates an appropriate compressor for the given compression method. + + \param uMethod + The compression method to create a compressor for. Can be one of #CompressionMethod values. + + \param pStorage + The current storage object. + */ + static CZipCompressor* CreateCompressor(WORD uMethod, CZipStorage* pStorage); + + +protected: + /** + Updates the current options with the new options. + + \param pOptions + The new options to apply. + */ + virtual void UpdateOptions(const COptions* pOptions) + { + } + /** + Updates CRC value while compression. + + \param pBuffer + A buffer with data for which the CRC value should be updated. + + \param uSize + The size of the buffer. + */ + void UpdateFileCrc(const void *pBuffer, DWORD uSize); + + /** + Updates CRC value while decompression. + + \param pBuffer + A buffer with data for which the CRC value should be updated. + + \param uSize + The size of the buffer. + */ + void UpdateCrc(const void *pBuffer, DWORD uSize); + + /** + Flushes data in the buffer into the storage, encrypting the data if needed. + + \note + Throws exceptions. + */ + void FlushWriteBuffer() + { + if (m_pCryptograph) + m_pCryptograph->Encode(m_pBuffer, (DWORD)m_uComprLeft); + m_pStorage->Write(m_pBuffer, (DWORD)m_uComprLeft, false); + m_uComprLeft = 0; + } + + /** + Initializes the internal buffer. + + \see + ReleaseBuffer + */ + void InitBuffer(); + + /** + Releases the internal buffer. + + \see + InitBuffer + */ + void ReleaseBuffer() + { + m_pBuffer.Release(); + } + + /** + Converts internal error code of the compressor to the ZipArchive Library error code. + + \param iErr + An internal error code. + + \return + A ZipArchive Library error code. + */ + virtual int ConvertInternalError(int iErr) const + { + return iErr; + } + + /** + Throws an exception with a given error code. + + \param iErr + An error code. + + \param bInternal + \c true, if \a iErr is an internal error code and needs a conversion to the ZipArchive Library error code; \c false otherwise. + + \note + Throws exceptions. + + \see + ConvertInternalError + */ + void ThrowError(int iErr, bool bInternal = false) + { + if (bInternal) + iErr = ConvertInternalError(iErr); + CZipException::Throw(iErr, m_pStorage->IsClosed(true) ? _T("") : (LPCTSTR)m_pStorage->m_pFile->GetFilePath()); + } +}; + +#if _MSC_VER > 1000 + #pragma warning( pop ) +#endif + +#endif -- cgit v1.2.3