mirror of
https://github.com/holub/mame
synced 2025-05-05 05:53:05 +03:00
269 lines
5.4 KiB
C++
269 lines
5.4 KiB
C++
// 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
|