blob: 34f10775cbf4772f187c89ab291021ec9bd8ea17 [file] [log] [blame]
// 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<CCoderInfo> Coders;
CRecordVector<CBindPair> BindPairs;
CRecordVector<CNum> PackStreams;
CRecordVector<UInt64> 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<UInt64> Values;
CRecordVector<bool> 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<UInt64> PackSizes;
CRecordVector<bool> PackCRCsDefined;
CRecordVector<UInt32> PackCRCs;
CObjectVector<CFolder> Folders;
CRecordVector<CNum> NumUnpackStreamsVector;
CObjectVector<CFileItem> Files;
CUInt64DefVector CTime;
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
CRecordVector<bool> 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