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