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