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
13namespace NArchive {
14namespace N7z {
15
16const UInt64 k_AES = 0x06F10701;
17
18typedef UInt32 CNum;
19const CNum kNumMax     = 0x7FFFFFFF;
20const CNum kNumNoIndex = 0xFFFFFFFF;
21
22struct 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
31struct CBindPair
32{
33  CNum InIndex;
34  CNum OutIndex;
35};
36
37struct 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
99struct 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
142struct 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
168struct 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
181struct 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