1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #ifndef _7ZIP_ARCHIVE_H
4 #define _7ZIP_ARCHIVE_H
5 
6 extern "C" {
7 #include "lib/7z/7zFile.h"
8 #include "lib/7z/7z.h"
9 }
10 
11 #include "ArchiveFactory.h"
12 #include "BufferedArchive.h"
13 #include <vector>
14 #include <string>
15 #include "IArchive.h"
16 
17 /**
18  * Creates LZMA/7zip compressed, single-file archives.
19  * @see CSevenZipArchive
20  */
21 class CSevenZipArchiveFactory : public IArchiveFactory {
22 public:
23 	CSevenZipArchiveFactory();
CheckForSolid()24 	bool CheckForSolid() const { return true; }
25 private:
26 	IArchive* DoCreateArchive(const std::string& filePath) const;
27 };
28 
29 
30 /**
31  * An LZMA/7zip compressed, single-file archive.
32  */
33 class CSevenZipArchive : public CBufferedArchive
34 {
35 public:
36 	CSevenZipArchive(const std::string& name);
37 	virtual ~CSevenZipArchive();
38 
39 	virtual bool IsOpen();
40 
41 	virtual unsigned int NumFiles() const;
42 	virtual bool GetFileImpl(unsigned int fid, std::vector<boost::uint8_t>& buffer);
43 	virtual void FileInfo(unsigned int fid, std::string& name, int& size) const;
44 	virtual bool HasLowReadingCost(unsigned int fid) const;
45 	virtual unsigned GetCrc32(unsigned int fid);
46 
47 private:
48 	UInt32 blockIndex;
49 	Byte* outBuffer;
50 	size_t outBufferSize;
51 
52 	/**
53 	 * How much more unpacked data may be allowed in a solid block,
54 	 * besides a meta-file.
55 	 * @see FileData#size
56 	 * @see FileData#unpackedSize
57 	 */
58 	static const size_t COST_LIMIT_UNPACK_OVERSIZE;
59 	/**
60 	 * Maximum allowed packed data allowed in a solid block
61 	 * that contains a meta-file.
62 	 * This is only checked for if the unpack-oversize limit was not met.
63 	 * @see FileData#size
64 	 * @see FileData#unpackedSize
65 	 */
66 	static const size_t COST_LIMIT_DISC_READ;
67 
68 	struct FileData
69 	{
70 		int fp;
71 		/**
72 		 * Real/unpacked size of the file in bytes.
73 		 * @see #unpackedSize
74 		 * @see #packedSize
75 		 */
76 		int size;
77 		std::string origName;
78 		unsigned int crc;
79 		/**
80 		 * How many bytes of files have to be unpacked to get to this file.
81 		 * This either equal to size, or is larger, if there are other files
82 		 * in the same solid block.
83 		 * @see #size
84 		 * @see #packedSize
85 		 */
86 		int unpackedSize;
87 		/**
88 		 * How many bytes of the archive have to be read
89 		 * from disc to get to this file.
90 		 * This may be smaller or larger then size,
91 		 * and is smaller then or equal to unpackedSize.
92 		 * @see #size
93 		 * @see #unpackedSize
94 		 */
95 		int packedSize;
96 	};
97 	int GetFileName(const CSzArEx* db, int i);
98 
99 	std::vector<FileData> fileData;
100 	UInt16 *tempBuf;
101 	size_t tempBufSize;
102 
103 	CFileInStream archiveStream;
104 	CSzArEx db;
105 	CLookToRead lookStream;
106 	ISzAlloc allocImp;
107 	ISzAlloc allocTempImp;
108 
109 	bool isOpen;
110 };
111 
112 #endif // _7ZIP_ARCHIVE_H
113