#pragma once #include #include #include "Stream.h" #include "ListBase.h" #include "ZipEntry.h" namespace Compression { // Manages compressed Zip archives and decompresses entries. class ZipArchive { public: ZipArchive(); ZipArchive(std::unique_ptr Stream); ZipArchive(std::unique_ptr Stream, bool LeaveOpen); ZipArchive(IO::Stream* Stream); ZipArchive(IO::Stream* Stream, bool LeaveOpen); ~ZipArchive(); // TODO: RemoveEntry(); // TODO: AddDirectory(); // Read all the file records in the central directory List ReadEntries(); // Add a file into the ZipArchive. ZipEntry AddFile(ZipCompressionMethod Method, const String& Path, const String& FileNameInZip, const String& Comment = ""); // Add a stream into the ZipArchive. ZipEntry AddStream(ZipCompressionMethod Method, const String& FileNameInZip, IO::Stream* Stream, const String& Comment = ""); // Extract the entry to the provided file path. void ExtractFile(ZipEntry& Entry, const String& FileName); // Extract the entry to the provided stream. void ExtractFile(ZipEntry& Entry, IO::Stream* Stream); // Extract the entry to the provided stream. void ExtractFile(ZipEntry& Entry, std::unique_ptr& Stream); // Get the underlying stream IO::Stream* GetBaseStream() const; // Close the ZipArchive and underlying stream void Close(); private: std::unique_ptr BaseStream; std::unique_ptr _CentralDir; uint64_t _CentralDirLength; uint64_t _ExistingFiles; bool _LeaveOpen; // Internal helper routine to parse the end of central directory record. void ReadFileInfo(); // Internal helper routine to calculate file offset. uint32_t GetFileOffset(uint32_t HeaderOffset); // Internal helper routine to read extra info. void ReadExtraInfo(uint64_t i, ZipEntry& Entry); // Internal helper routine to clean a file name String NormalizeFileName(const String& FileName); // Internal routine to calculate crc and sizes void UpdateCrcAndSizes(ZipEntry& Entry); // Internal routine to write the file header void WriteLocalHeader(ZipEntry& Entry); // Internal routine to create extra info void CreateExtraInfo(ZipEntry& Entry, IO::Stream* Output); // Internal routine to get maximum 32bit size uint32_t Get32BitSize(uint64_t Size); }; }