Home | History | Annotate | Download | only in 7z
      1 // 7zIn.h
      2 
      3 #ifndef __7Z_IN_H
      4 #define __7Z_IN_H
      5 
      6 #include "../../../Common/MyCom.h"
      7 
      8 #include "../../IPassword.h"
      9 #include "../../IStream.h"
     10 
     11 #include "../../Common/CreateCoder.h"
     12 #include "../../Common/InBuffer.h"
     13 
     14 #include "7zItem.h"
     15 
     16 namespace NArchive {
     17 namespace N7z {
     18 
     19 struct CInArchiveInfo
     20 {
     21   CArchiveVersion Version;
     22   UInt64 StartPosition;
     23   UInt64 StartPositionAfterHeader;
     24   UInt64 DataStartPosition;
     25   UInt64 DataStartPosition2;
     26   CRecordVector<UInt64> FileInfoPopIDs;
     27   void Clear()
     28   {
     29     FileInfoPopIDs.Clear();
     30   }
     31 };
     32 
     33 struct CArchiveDatabaseEx: public CArchiveDatabase
     34 {
     35   CInArchiveInfo ArchiveInfo;
     36   CRecordVector<UInt64> PackStreamStartPositions;
     37   CRecordVector<CNum> FolderStartPackStreamIndex;
     38   CRecordVector<CNum> FolderStartFileIndex;
     39   CRecordVector<CNum> FileIndexToFolderIndexMap;
     40 
     41   UInt64 HeadersSize;
     42   UInt64 PhySize;
     43 
     44   void Clear()
     45   {
     46     CArchiveDatabase::Clear();
     47     ArchiveInfo.Clear();
     48     PackStreamStartPositions.Clear();
     49     FolderStartPackStreamIndex.Clear();
     50     FolderStartFileIndex.Clear();
     51     FileIndexToFolderIndexMap.Clear();
     52 
     53     HeadersSize = 0;
     54     PhySize = 0;
     55   }
     56 
     57   void FillFolderStartPackStream();
     58   void FillStartPos();
     59   void FillFolderStartFileIndex();
     60 
     61   void Fill()
     62   {
     63     FillFolderStartPackStream();
     64     FillStartPos();
     65     FillFolderStartFileIndex();
     66   }
     67 
     68   UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
     69   {
     70     return ArchiveInfo.DataStartPosition +
     71         PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];
     72   }
     73 
     74   UInt64 GetFolderFullPackSize(int folderIndex) const
     75   {
     76     CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
     77     const CFolder &folder = Folders[folderIndex];
     78     UInt64 size = 0;
     79     for (int i = 0; i < folder.PackStreams.Size(); i++)
     80       size += PackSizes[packStreamIndex + i];
     81     return size;
     82   }
     83 
     84   UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
     85   {
     86     return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
     87   }
     88 
     89   UInt64 GetFilePackSize(CNum fileIndex) const
     90   {
     91     CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
     92     if (folderIndex != kNumNoIndex)
     93       if (FolderStartFileIndex[folderIndex] == fileIndex)
     94         return GetFolderFullPackSize(folderIndex);
     95     return 0;
     96   }
     97 };
     98 
     99 class CInByte2
    100 {
    101   const Byte *_buffer;
    102   size_t _size;
    103 public:
    104   size_t _pos;
    105   void Init(const Byte *buffer, size_t size)
    106   {
    107     _buffer = buffer;
    108     _size = size;
    109     _pos = 0;
    110   }
    111   Byte ReadByte();
    112   void ReadBytes(Byte *data, size_t size);
    113   void SkipData(UInt64 size);
    114   void SkipData();
    115   UInt64 ReadNumber();
    116   CNum ReadNum();
    117   UInt32 ReadUInt32();
    118   UInt64 ReadUInt64();
    119   void ReadString(UString &s);
    120 };
    121 
    122 class CStreamSwitch;
    123 
    124 const UInt32 kHeaderSize = 32;
    125 
    126 class CInArchive
    127 {
    128   friend class CStreamSwitch;
    129 
    130   CMyComPtr<IInStream> _stream;
    131 
    132   CObjectVector<CInByte2> _inByteVector;
    133   CInByte2 *_inByteBack;
    134 
    135   UInt64 _arhiveBeginStreamPosition;
    136 
    137   Byte _header[kHeaderSize];
    138 
    139   UInt64 HeadersSize;
    140 
    141   void AddByteStream(const Byte *buffer, size_t size)
    142   {
    143     _inByteVector.Add(CInByte2());
    144     _inByteBack = &_inByteVector.Back();
    145     _inByteBack->Init(buffer, size);
    146   }
    147 
    148   void DeleteByteStream()
    149   {
    150     _inByteVector.DeleteBack();
    151     if (!_inByteVector.IsEmpty())
    152       _inByteBack = &_inByteVector.Back();
    153   }
    154 
    155 private:
    156   HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
    157 
    158   void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
    159   Byte ReadByte() { return _inByteBack->ReadByte(); }
    160   UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }
    161   CNum ReadNum() { return _inByteBack->ReadNum(); }
    162   UInt64 ReadID() { return _inByteBack->ReadNumber(); }
    163   UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); }
    164   UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
    165   void SkipData(UInt64 size) { _inByteBack->SkipData(size); }
    166   void SkipData() { _inByteBack->SkipData(); }
    167   void WaitAttribute(UInt64 attribute);
    168 
    169   void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
    170   void GetNextFolderItem(CFolder &itemInfo);
    171   void ReadHashDigests(int numItems,
    172       CBoolVector &digestsDefined, CRecordVector<UInt32> &digests);
    173 
    174   void ReadPackInfo(
    175       UInt64 &dataOffset,
    176       CRecordVector<UInt64> &packSizes,
    177       CBoolVector &packCRCsDefined,
    178       CRecordVector<UInt32> &packCRCs);
    179 
    180   void ReadUnpackInfo(
    181       const CObjectVector<CByteBuffer> *dataVector,
    182       CObjectVector<CFolder> &folders);
    183 
    184   void ReadSubStreamsInfo(
    185       const CObjectVector<CFolder> &folders,
    186       CRecordVector<CNum> &numUnpackStreamsInFolders,
    187       CRecordVector<UInt64> &unpackSizes,
    188       CBoolVector &digestsDefined,
    189       CRecordVector<UInt32> &digests);
    190 
    191   void ReadStreamsInfo(
    192       const CObjectVector<CByteBuffer> *dataVector,
    193       UInt64 &dataOffset,
    194       CRecordVector<UInt64> &packSizes,
    195       CBoolVector &packCRCsDefined,
    196       CRecordVector<UInt32> &packCRCs,
    197       CObjectVector<CFolder> &folders,
    198       CRecordVector<CNum> &numUnpackStreamsInFolders,
    199       CRecordVector<UInt64> &unpackSizes,
    200       CBoolVector &digestsDefined,
    201       CRecordVector<UInt32> &digests);
    202 
    203 
    204   void ReadBoolVector(int numItems, CBoolVector &v);
    205   void ReadBoolVector2(int numItems, CBoolVector &v);
    206   void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
    207       CUInt64DefVector &v, int numFiles);
    208   HRESULT ReadAndDecodePackedStreams(
    209       DECL_EXTERNAL_CODECS_LOC_VARS
    210       UInt64 baseOffset, UInt64 &dataOffset,
    211       CObjectVector<CByteBuffer> &dataVector
    212       #ifndef _NO_CRYPTO
    213       , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
    214       #endif
    215       );
    216   HRESULT ReadHeader(
    217       DECL_EXTERNAL_CODECS_LOC_VARS
    218       CArchiveDatabaseEx &db
    219       #ifndef _NO_CRYPTO
    220       ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
    221       #endif
    222       );
    223   HRESULT ReadDatabase2(
    224       DECL_EXTERNAL_CODECS_LOC_VARS
    225       CArchiveDatabaseEx &db
    226       #ifndef _NO_CRYPTO
    227       ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
    228       #endif
    229       );
    230 public:
    231   HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
    232   void Close();
    233 
    234   HRESULT ReadDatabase(
    235       DECL_EXTERNAL_CODECS_LOC_VARS
    236       CArchiveDatabaseEx &db
    237       #ifndef _NO_CRYPTO
    238       ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
    239       #endif
    240       );
    241 };
    242 
    243 }}
    244 
    245 #endif
    246