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;
IsSimpleCoderCCoderInfo28   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 
CFolderCFolder46   CFolder(): UnpackCRCDefined(false) {}
47 
GetUnpackSizeCFolder48   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 
GetNumOutStreamsCFolder58   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 
FindBindPairForInStreamCFolder66   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   }
FindBindPairForOutStreamCFolder73   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   }
FindPackStreamArrayIndexCFolder80   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 
IsEncryptedCFolder88   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 
ClearCUInt64DefVector104   void Clear()
105   {
106     Values.Clear();
107     Defined.Clear();
108   }
109 
ReserveDownCUInt64DefVector110   void ReserveDown()
111   {
112     Values.ReserveDown();
113     Values.ReserveDown();
114   }
115 
GetItemCUInt64DefVector116   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 
SetItemCUInt64DefVector127   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 
CheckSizeCUInt64DefVector139   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 
CFileItemCFileItem155   CFileItem():
156     HasStream(true),
157     IsDir(false),
158     CrcDefined(false),
159     AttribDefined(false)
160       {}
SetAttribCFileItem161   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 
ClearCArchiveDatabase196   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 
ReserveDownCArchiveDatabase211   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 
IsEmptyCArchiveDatabase226   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 
CheckNumFilesCArchiveDatabase236   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 
IsSolidCArchiveDatabase247   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   }
IsItemAntiCArchiveDatabase254   bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); }
SetItemAntiCArchiveDatabase255   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