1 #ifndef SEVENZIPFILE_H
2 #define SEVENZIPFILE_H
3 
4 #include <QObject>
5 #include <QStringList>
6 #include <QList>
7 #include <QMap>
8 #include <QHash>
9 #include <QString>
10 #include <QDateTime>
11 #include <QByteArray>
12 #include <QThread>
13 #include <QWaitCondition>
14 #include <QMutex>
15 
16 #include "bigbytearray.h"
17 
18 extern "C" {
19 #include "lzma/7z.h"
20 #include "lzma/7zAlloc.h"
21 #include "lzma/7zCrc.h"
22 #include "lzma/7zFile.h"
23 }
24 
25 class SevenZipMetaData
26 {
27 	public:
28 		explicit SevenZipMetaData(QString name = QString(), quint64 size = 0, QDateTime date = QDateTime(), QString crc = QString())
29 		{
30 			setName(name);
31 			setSize(size);
32 			setDate(date);
33 			setCrc(crc);
34 		}
35 
setName(QString name)36 		void setName(QString name) { m_name = name; }
name()37 		QString &name() { return m_name; }
setSize(quint64 size)38 		void setSize(quint64 size) { m_size = size; }
size()39 		quint64 size() { return m_size; }
setDate(QDateTime date)40 		void setDate(QDateTime date) { m_date = date; }
date()41 		QDateTime &date() { return m_date; }
setCrc(QString crc)42 		void setCrc(QString crc) { m_crc = crc; }
crc()43 		QString &crc() { return m_crc; }
44 
45 	private:
46 		QString m_name;
47 		quint64 m_size;
48 		QDateTime m_date;
49 		QString m_crc;
50 };
51 
52 class SevenZipExtractorThread : public QThread
53 {
54 	Q_OBJECT
55 
56 	public:
57 		explicit SevenZipExtractorThread(QObject *parent = 0);
58 		~SevenZipExtractorThread();
59 
quitFlag()60 		bool quitFlag() { return m_quitFlag; }
setQuitFlag(bool flag)61 		void setQuitFlag(bool flag) { m_quitFlag = flag; }
isActive()62 		bool isActive() { return m_active; }
fileCount()63 		int fileCount() { return m_fileCount; }
64 		void setParams(CSzArEx *db, ILookInStream *lookInStream, uint fileIndex, UInt32_7z *blockIndex, Byte **buffer, size_t *bufferSize, size_t *offset, size_t *sizeProcessed, ISzAlloc *allocImp, ISzAlloc *allocTempImp);
result()65 		SRes result() { return m_result; }
waitMutex()66 		QMutex &waitMutex() { return m_waitMutex; }
waitCondition()67 		QWaitCondition &waitCondition() { return m_waitCondition; }
68 
69 	public slots:
70 
71 	protected:
72 		void run();
73 
74 	signals:
75 		void extracted(uint);
76 		void failed(uint);
77 
78 	private:
79 		bool m_quitFlag;
80 		bool m_active;
81 		int m_fileCount;
82 		CSzArEx *m_db;
83 		ILookInStream *m_lookInStream;
84 		uint m_fileIndex;
85 		UInt32_7z *m_blockIndex;
86 		Byte **m_buffer;
87 		size_t *m_bufferSize;
88 		size_t *m_offset;
89 		size_t *m_sizeProcessed;
90 		ISzAlloc *m_allocImp;
91 		ISzAlloc *m_allocTempImp;
92 		SRes m_result;
93 		QMutex m_waitMutex;
94 		QWaitCondition m_waitCondition;
95 };
96 
97 class SevenZipFile : public QObject
98 {
99 	Q_OBJECT
100 
101 	public:
102 		explicit SevenZipFile(QString fileName = QString(), QObject *parent = 0);
103 		~SevenZipFile();
104 
fileName()105 		QString &fileName() { return m_fileName; }
lastError()106 		QString &lastError() { return m_lastError; }
hasError()107 		bool hasError() { return !m_lastError.isEmpty(); }
isOpen()108 		bool isOpen() { return m_isOpen; }
isFillingDictionary()109 		bool isFillingDictionary() { return m_fillingDictionary; }
entryList()110 		QList<SevenZipMetaData> &entryList() { return m_entryList; }
111 		quint64 read(QString name, QByteArray *buffer);
112 		quint64 read(uint index, QByteArray *buffer, bool *async = 0);
113 		quint64 readBig(uint index, BigByteArray *buffer, bool *async = 0);
indexOfName(const QString & name)114 		int indexOfName(const QString &name) { if ( m_nameToIndexCache.contains(name) ) return m_nameToIndexCache.value(name); else return -1; }
indexOfCrc(const QString & crc)115 		int indexOfCrc(const QString &crc) { if ( m_crcToIndexCache.contains(crc) ) return m_crcToIndexCache.value(crc); else return -1; }
isCrcDuplicate(const QString & crc)116 		bool isCrcDuplicate(const QString &crc) { if ( m_crcDuplicates.contains(crc) ) return m_crcDuplicates.value(crc); else return false; }
userData()117 		QString &userData() { return m_userData; }
setUserData(const QString & data)118 		void setUserData(const QString &data) { m_userData = data; }
119 
120 	signals:
121 		void opened();
122 		void closed();
123 		void error(QString);
124 		void dataReady();
125 
126 	public slots:
127 		bool open(QString fileName = QString());
128 		void close();
129 
130 	private slots:
131 		void asyncExtractionFinished(uint index);
132 
133 	private:
134 		QDateTime convertFileTime(const CNtfsFileTime *ft);
135 		void createEntryList();
136 		QString errorCodeToString(SRes errorCode);
db()137 		CSzArEx *db() { return &m_db; }
138 
139 		CSzArEx m_db;
140 		ISzAlloc m_allocImp;
141 		ISzAlloc m_allocTempImp;
142 		CFileInStream m_archiveStream;
143 		CLookToRead m_lookStream;
144 		UInt32_7z m_blockIndex;
145 		size_t m_bufferSize;
146 		size_t m_sizeProcessed;
147 		Byte *m_buffer;
148 		QMap<uint, size_t> m_offsetMap;
149 		QList<SevenZipMetaData> m_entryList;
150 		QString m_fileName;
151 		QString m_lastError;
152 		SevenZipExtractorThread *m_extractor;
153 		bool m_isOpen;
154 		bool m_firstExtraction;
155 		bool m_fillingDictionary;
156 		QString m_userData;
157 		QHash<QString, int> m_nameToIndexCache;
158 		QHash<QString, int> m_crcToIndexCache;
159 		QHash<QString, bool> m_crcDuplicates;
160 };
161 
162 #endif
163