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