// 7zItem.h #ifndef __7Z_ITEM_H #define __7Z_ITEM_H #include "../../../Common/Buffer.h" #include "../../../Common/MyString.h" #include "../../Common/MethodId.h" #include "7zHeader.h" namespace NArchive { namespace N7z { const UInt64 k_AES = 0x06F10701; typedef UInt32 CNum; const CNum kNumMax = 0x7FFFFFFF; const CNum kNumNoIndex = 0xFFFFFFFF; struct CCoderInfo { CMethodId MethodID; CByteBuffer Props; CNum NumInStreams; CNum NumOutStreams; bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); } }; struct CBindPair { CNum InIndex; CNum OutIndex; }; struct CFolder { CObjectVector Coders; CRecordVector BindPairs; CRecordVector PackStreams; CRecordVector UnpackSizes; UInt32 UnpackCRC; bool UnpackCRCDefined; CFolder(): UnpackCRCDefined(false) {} UInt64 GetUnpackSize() const // test it { if (UnpackSizes.IsEmpty()) return 0; for (int i = UnpackSizes.Size() - 1; i >= 0; i--) if (FindBindPairForOutStream(i) < 0) return UnpackSizes[i]; throw 1; } CNum GetNumOutStreams() const { CNum result = 0; for (int i = 0; i < Coders.Size(); i++) result += Coders[i].NumOutStreams; return result; } int FindBindPairForInStream(CNum inStreamIndex) const { for(int i = 0; i < BindPairs.Size(); i++) if (BindPairs[i].InIndex == inStreamIndex) return i; return -1; } int FindBindPairForOutStream(CNum outStreamIndex) const { for(int i = 0; i < BindPairs.Size(); i++) if (BindPairs[i].OutIndex == outStreamIndex) return i; return -1; } int FindPackStreamArrayIndex(CNum inStreamIndex) const { for(int i = 0; i < PackStreams.Size(); i++) if (PackStreams[i] == inStreamIndex) return i; return -1; } bool IsEncrypted() const { for (int i = Coders.Size() - 1; i >= 0; i--) if (Coders[i].MethodID == k_AES) return true; return false; } bool CheckStructure() const; }; struct CUInt64DefVector { CRecordVector Values; CRecordVector Defined; void Clear() { Values.Clear(); Defined.Clear(); } void ReserveDown() { Values.ReserveDown(); Values.ReserveDown(); } bool GetItem(int index, UInt64 &value) const { if (index < Defined.Size() && Defined[index]) { value = Values[index]; return true; } value = 0; return false; } void SetItem(int index, bool defined, UInt64 value) { while (index >= Defined.Size()) Defined.Add(false); Defined[index] = defined; if (!defined) return; while (index >= Values.Size()) Values.Add(0); Values[index] = value; } bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; } }; struct CFileItem { UInt64 Size; UInt32 Attrib; UInt32 Crc; UString Name; bool HasStream; // Test it !!! it means that there is // stream in some folder. It can be empty stream bool IsDir; bool CrcDefined; bool AttribDefined; CFileItem(): HasStream(true), IsDir(false), CrcDefined(false), AttribDefined(false) {} void SetAttrib(UInt32 attrib) { AttribDefined = true; Attrib = attrib; } }; struct CFileItem2 { UInt64 CTime; UInt64 ATime; UInt64 MTime; UInt64 StartPos; bool CTimeDefined; bool ATimeDefined; bool MTimeDefined; bool StartPosDefined; bool IsAnti; }; struct CArchiveDatabase { CRecordVector PackSizes; CRecordVector PackCRCsDefined; CRecordVector PackCRCs; CObjectVector Folders; CRecordVector NumUnpackStreamsVector; CObjectVector Files; CUInt64DefVector CTime; CUInt64DefVector ATime; CUInt64DefVector MTime; CUInt64DefVector StartPos; CRecordVector IsAnti; void Clear() { PackSizes.Clear(); PackCRCsDefined.Clear(); PackCRCs.Clear(); Folders.Clear(); NumUnpackStreamsVector.Clear(); Files.Clear(); CTime.Clear(); ATime.Clear(); MTime.Clear(); StartPos.Clear(); IsAnti.Clear(); } void ReserveDown() { PackSizes.ReserveDown(); PackCRCsDefined.ReserveDown(); PackCRCs.ReserveDown(); Folders.ReserveDown(); NumUnpackStreamsVector.ReserveDown(); Files.ReserveDown(); CTime.ReserveDown(); ATime.ReserveDown(); MTime.ReserveDown(); StartPos.ReserveDown(); IsAnti.ReserveDown(); } bool IsEmpty() const { return (PackSizes.IsEmpty() && PackCRCsDefined.IsEmpty() && PackCRCs.IsEmpty() && Folders.IsEmpty() && NumUnpackStreamsVector.IsEmpty() && Files.IsEmpty()); } bool CheckNumFiles() const { int size = Files.Size(); return ( CTime.CheckSize(size) && ATime.CheckSize(size) && MTime.CheckSize(size) && StartPos.CheckSize(size) && (size == IsAnti.Size() || IsAnti.Size() == 0)); } bool IsSolid() const { for (int i = 0; i < NumUnpackStreamsVector.Size(); i++) if (NumUnpackStreamsVector[i] > 1) return true; return false; } bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); } void SetItemAnti(int index, bool isAnti) { while (index >= IsAnti.Size()) IsAnti.Add(false); IsAnti[index] = isAnti; } void GetFile(int index, CFileItem &file, CFileItem2 &file2) const; void AddFile(const CFileItem &file, const CFileItem2 &file2); }; }} #endif