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