Home | History | Annotate | Download | only in 7z
      1 // 7zItem.h
      2 
      3 #ifndef __7Z_ITEM_H
      4 #define __7Z_ITEM_H
      5 
      6 #include "../../../Common/Buffer.h"
      7 #include "../../../Common/MyString.h"
      8 
      9 #include "../../Common/MethodId.h"
     10 
     11 #include "7zHeader.h"
     12 
     13 namespace NArchive {
     14 namespace N7z {
     15 
     16 const UInt64 k_AES = 0x06F10701;
     17 
     18 typedef UInt32 CNum;
     19 const CNum kNumMax     = 0x7FFFFFFF;
     20 const CNum kNumNoIndex = 0xFFFFFFFF;
     21 
     22 struct CCoderInfo
     23 {
     24   CMethodId MethodID;
     25   CByteBuffer Props;
     26   CNum NumInStreams;
     27   CNum NumOutStreams;
     28   bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
     29 };
     30 
     31 struct CBindPair
     32 {
     33   CNum InIndex;
     34   CNum OutIndex;
     35 };
     36 
     37 struct CFolder
     38 {
     39   CObjectVector<CCoderInfo> Coders;
     40   CRecordVector<CBindPair> BindPairs;
     41   CRecordVector<CNum> PackStreams;
     42   CRecordVector<UInt64> UnpackSizes;
     43   UInt32 UnpackCRC;
     44   bool UnpackCRCDefined;
     45 
     46   CFolder(): UnpackCRCDefined(false) {}
     47 
     48   UInt64 GetUnpackSize() const // test it
     49   {
     50     if (UnpackSizes.IsEmpty())
     51       return 0;
     52     for (int i = UnpackSizes.Size() - 1; i >= 0; i--)
     53       if (FindBindPairForOutStream(i) < 0)
     54         return UnpackSizes[i];
     55     throw 1;
     56   }
     57 
     58   CNum GetNumOutStreams() const
     59   {
     60     CNum result = 0;
     61     for (int i = 0; i < Coders.Size(); i++)
     62       result += Coders[i].NumOutStreams;
     63     return result;
     64   }
     65 
     66   int FindBindPairForInStream(CNum inStreamIndex) const
     67   {
     68     for(int i = 0; i < BindPairs.Size(); i++)
     69       if (BindPairs[i].InIndex == inStreamIndex)
     70         return i;
     71     return -1;
     72   }
     73   int FindBindPairForOutStream(CNum outStreamIndex) const
     74   {
     75     for(int i = 0; i < BindPairs.Size(); i++)
     76       if (BindPairs[i].OutIndex == outStreamIndex)
     77         return i;
     78     return -1;
     79   }
     80   int FindPackStreamArrayIndex(CNum inStreamIndex) const
     81   {
     82     for(int i = 0; i < PackStreams.Size(); i++)
     83       if (PackStreams[i] == inStreamIndex)
     84         return i;
     85     return -1;
     86   }
     87 
     88   bool IsEncrypted() const
     89   {
     90     for (int i = Coders.Size() - 1; i >= 0; i--)
     91       if (Coders[i].MethodID == k_AES)
     92         return true;
     93     return false;
     94   }
     95 
     96   bool CheckStructure() const;
     97 };
     98 
     99 struct CUInt64DefVector
    100 {
    101   CRecordVector<UInt64> Values;
    102   CRecordVector<bool> Defined;
    103 
    104   void Clear()
    105   {
    106     Values.Clear();
    107     Defined.Clear();
    108   }
    109 
    110   void ReserveDown()
    111   {
    112     Values.ReserveDown();
    113     Values.ReserveDown();
    114   }
    115 
    116   bool GetItem(int index, UInt64 &value) const
    117   {
    118     if (index < Defined.Size() && Defined[index])
    119     {
    120       value = Values[index];
    121       return true;
    122     }
    123     value = 0;
    124     return false;
    125   }
    126 
    127   void SetItem(int index, bool defined, UInt64 value)
    128   {
    129     while (index >= Defined.Size())
    130       Defined.Add(false);
    131     Defined[index] = defined;
    132     if (!defined)
    133       return;
    134     while (index >= Values.Size())
    135       Values.Add(0);
    136     Values[index] = value;
    137   }
    138 
    139   bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; }
    140 };
    141 
    142 struct CFileItem
    143 {
    144   UInt64 Size;
    145   UInt32 Attrib;
    146   UInt32 Crc;
    147   UString Name;
    148 
    149   bool HasStream; // Test it !!! it means that there is
    150                   // stream in some folder. It can be empty stream
    151   bool IsDir;
    152   bool CrcDefined;
    153   bool AttribDefined;
    154 
    155   CFileItem():
    156     HasStream(true),
    157     IsDir(false),
    158     CrcDefined(false),
    159     AttribDefined(false)
    160       {}
    161   void SetAttrib(UInt32 attrib)
    162   {
    163     AttribDefined = true;
    164     Attrib = attrib;
    165   }
    166 };
    167 
    168 struct CFileItem2
    169 {
    170   UInt64 CTime;
    171   UInt64 ATime;
    172   UInt64 MTime;
    173   UInt64 StartPos;
    174   bool CTimeDefined;
    175   bool ATimeDefined;
    176   bool MTimeDefined;
    177   bool StartPosDefined;
    178   bool IsAnti;
    179 };
    180 
    181 struct CArchiveDatabase
    182 {
    183   CRecordVector<UInt64> PackSizes;
    184   CRecordVector<bool> PackCRCsDefined;
    185   CRecordVector<UInt32> PackCRCs;
    186   CObjectVector<CFolder> Folders;
    187   CRecordVector<CNum> NumUnpackStreamsVector;
    188   CObjectVector<CFileItem> Files;
    189 
    190   CUInt64DefVector CTime;
    191   CUInt64DefVector ATime;
    192   CUInt64DefVector MTime;
    193   CUInt64DefVector StartPos;
    194   CRecordVector<bool> IsAnti;
    195 
    196   void Clear()
    197   {
    198     PackSizes.Clear();
    199     PackCRCsDefined.Clear();
    200     PackCRCs.Clear();
    201     Folders.Clear();
    202     NumUnpackStreamsVector.Clear();
    203     Files.Clear();
    204     CTime.Clear();
    205     ATime.Clear();
    206     MTime.Clear();
    207     StartPos.Clear();
    208     IsAnti.Clear();
    209   }
    210 
    211   void ReserveDown()
    212   {
    213     PackSizes.ReserveDown();
    214     PackCRCsDefined.ReserveDown();
    215     PackCRCs.ReserveDown();
    216     Folders.ReserveDown();
    217     NumUnpackStreamsVector.ReserveDown();
    218     Files.ReserveDown();
    219     CTime.ReserveDown();
    220     ATime.ReserveDown();
    221     MTime.ReserveDown();
    222     StartPos.ReserveDown();
    223     IsAnti.ReserveDown();
    224   }
    225 
    226   bool IsEmpty() const
    227   {
    228     return (PackSizes.IsEmpty() &&
    229       PackCRCsDefined.IsEmpty() &&
    230       PackCRCs.IsEmpty() &&
    231       Folders.IsEmpty() &&
    232       NumUnpackStreamsVector.IsEmpty() &&
    233       Files.IsEmpty());
    234   }
    235 
    236   bool CheckNumFiles() const
    237   {
    238     int size = Files.Size();
    239     return (
    240       CTime.CheckSize(size) &&
    241       ATime.CheckSize(size) &&
    242       MTime.CheckSize(size) &&
    243       StartPos.CheckSize(size) &&
    244       (size == IsAnti.Size() || IsAnti.Size() == 0));
    245   }
    246 
    247   bool IsSolid() const
    248   {
    249     for (int i = 0; i < NumUnpackStreamsVector.Size(); i++)
    250       if (NumUnpackStreamsVector[i] > 1)
    251         return true;
    252     return false;
    253   }
    254   bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); }
    255   void SetItemAnti(int index, bool isAnti)
    256   {
    257     while (index >= IsAnti.Size())
    258       IsAnti.Add(false);
    259     IsAnti[index] = isAnti;
    260   }
    261 
    262   void GetFile(int index, CFileItem &file, CFileItem2 &file2) const;
    263   void AddFile(const CFileItem &file, const CFileItem2 &file2);
    264 };
    265 
    266 }}
    267 
    268 #endif
    269