xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Cab/CabIn.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // Archive/CabIn.h
2 
3 #ifndef ZIP7_INC_ARCHIVE_CAB_IN_H
4 #define ZIP7_INC_ARCHIVE_CAB_IN_H
5 
6 #include "../../../Common/MyBuffer.h"
7 #include "../../../Common/MyCom.h"
8 
9 #include "../../Common/InBuffer.h"
10 
11 #include "CabItem.h"
12 
13 namespace NArchive {
14 namespace NCab {
15 
16 struct COtherArc
17 {
18   AString FileName;
19   AString DiskName;
20 
ClearCOtherArc21   void Clear()
22   {
23     FileName.Empty();
24     DiskName.Empty();
25   }
26 };
27 
28 
29 struct CArchInfo
30 {
31   Byte VersionMinor; // cabinet file format version, minor
32   Byte VersionMajor; // cabinet file format version, major
33   UInt32 NumFolders; // number of CFFOLDER entries in this cabinet
34   UInt32 NumFiles;   // number of CFFILE entries in this cabinet
35   UInt32 Flags;      // cabinet file option indicators
36   UInt32 SetID;      // must be the same for all cabinets in a set
37   UInt32 CabinetNumber; // number of this cabinet file in a set
38 
39   UInt16 PerCabinet_AreaSize; // (optional) size of per-cabinet reserved area
40   Byte PerFolder_AreaSize;    // (optional) size of per-folder reserved area
41   Byte PerDataBlock_AreaSize; // (optional) size of per-datablock reserved area
42 
43   COtherArc PrevArc; // prev link can skip some volumes !!!
44   COtherArc NextArc;
45 
ReserveBlockPresentCArchInfo46   bool ReserveBlockPresent() const { return (Flags & NHeader::NArcFlags::kReservePresent) != 0; }
IsTherePrevCArchInfo47   bool IsTherePrev() const { return (Flags & NHeader::NArcFlags::kPrevCabinet) != 0; }
IsThereNextCArchInfo48   bool IsThereNext() const { return (Flags & NHeader::NArcFlags::kNextCabinet) != 0; }
GetDataBlockReserveSizeCArchInfo49   Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlock_AreaSize : 0); }
50 
CArchInfoCArchInfo51   CArchInfo()
52   {
53     PerCabinet_AreaSize = 0;
54     PerFolder_AreaSize = 0;
55     PerDataBlock_AreaSize = 0;
56   }
57 
ClearCArchInfo58   void Clear()
59   {
60     PerCabinet_AreaSize = 0;
61     PerFolder_AreaSize = 0;
62     PerDataBlock_AreaSize = 0;
63 
64     PrevArc.Clear();
65     NextArc.Clear();
66   }
67 };
68 
69 
70 struct CInArcInfo: public CArchInfo
71 {
72   UInt32 Size; // size of this cabinet file in bytes
73   UInt32 FileHeadersOffset; // offset of the first CFFILE entry
74 
75   bool Parse(const Byte *p);
76 };
77 
78 
79 struct CDatabase
80 {
81   CRecordVector<CFolder> Folders;
82   CObjectVector<CItem> Items;
83   UInt64 StartPosition;
84   CInArcInfo ArcInfo;
85 
ClearCDatabase86   void Clear()
87   {
88     ArcInfo.Clear();
89     Folders.Clear();
90     Items.Clear();
91   }
92 
IsTherePrevFolderCDatabase93   bool IsTherePrevFolder() const
94   {
95     FOR_VECTOR (i, Items)
96       if (Items[i].ContinuedFromPrev())
97         return true;
98     return false;
99   }
100 
GetNumberOfNewFoldersCDatabase101   int GetNumberOfNewFolders() const
102   {
103     int res = (int)Folders.Size();
104     if (IsTherePrevFolder())
105       res--;
106     return res;
107   }
108 };
109 
110 
111 struct CDatabaseEx: public CDatabase
112 {
113   CMyComPtr<IInStream> Stream;
114 };
115 
116 
117 struct CMvItem
118 {
119   unsigned VolumeIndex;
120   unsigned ItemIndex;
121 };
122 
123 
124 class CMvDatabaseEx
125 {
126   bool AreItemsEqual(unsigned i1, unsigned i2);
127 
128 public:
129   CObjectVector<CDatabaseEx> Volumes;
130   CRecordVector<CMvItem> Items;
131   CRecordVector<int> StartFolderOfVol; // can be negative
132   CRecordVector<unsigned> FolderStartFileIndex;
133 
GetFolderIndex(const CMvItem * mvi)134   int GetFolderIndex(const CMvItem *mvi) const
135   {
136     const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
137     return StartFolderOfVol[mvi->VolumeIndex] +
138         db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size());
139   }
140 
Clear()141   void Clear()
142   {
143     Volumes.Clear();
144     Items.Clear();
145     StartFolderOfVol.Clear();
146     FolderStartFileIndex.Clear();
147   }
148 
149   void FillSortAndShrink();
150   bool Check();
151 };
152 
153 
154 class CInArchive
155 {
156   CInBufferBase _inBuffer;
157   CByteBuffer _tempBuf;
158 
159   void Skip(unsigned size);
160   void Read(Byte *data, unsigned size);
161   void ReadName(AString &s);
162   void ReadOtherArc(COtherArc &oa);
163   HRESULT Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);
164 
165 public:
166   bool IsArc;
167   bool ErrorInNames;
168   bool UnexpectedEnd;
169   bool HeaderError;
170 
171   HRESULT Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);
172 };
173 
174 }}
175 
176 #endif
177