177 lines
3.7 KiB
C++
177 lines
3.7 KiB
C++
// Archive/CabIn.h
|
|
|
|
#ifndef __ARCHIVE_CAB_IN_H
|
|
#define __ARCHIVE_CAB_IN_H
|
|
|
|
#include "../../../Common/MyBuffer.h"
|
|
#include "../../../Common/MyCom.h"
|
|
|
|
#include "../../Common/InBuffer.h"
|
|
|
|
#include "CabItem.h"
|
|
|
|
namespace NArchive {
|
|
namespace NCab {
|
|
|
|
struct COtherArc
|
|
{
|
|
AString FileName;
|
|
AString DiskName;
|
|
|
|
void Clear()
|
|
{
|
|
FileName.Empty();
|
|
DiskName.Empty();
|
|
}
|
|
};
|
|
|
|
|
|
struct CArchInfo
|
|
{
|
|
Byte VersionMinor; // cabinet file format version, minor
|
|
Byte VersionMajor; // cabinet file format version, major
|
|
UInt32 NumFolders; // number of CFFOLDER entries in this cabinet
|
|
UInt32 NumFiles; // number of CFFILE entries in this cabinet
|
|
UInt32 Flags; // cabinet file option indicators
|
|
UInt32 SetID; // must be the same for all cabinets in a set
|
|
UInt32 CabinetNumber; // number of this cabinet file in a set
|
|
|
|
UInt16 PerCabinet_AreaSize; // (optional) size of per-cabinet reserved area
|
|
Byte PerFolder_AreaSize; // (optional) size of per-folder reserved area
|
|
Byte PerDataBlock_AreaSize; // (optional) size of per-datablock reserved area
|
|
|
|
COtherArc PrevArc; // prev link can skip some volumes !!!
|
|
COtherArc NextArc;
|
|
|
|
bool ReserveBlockPresent() const { return (Flags & NHeader::NArcFlags::kReservePresent) != 0; }
|
|
bool IsTherePrev() const { return (Flags & NHeader::NArcFlags::kPrevCabinet) != 0; }
|
|
bool IsThereNext() const { return (Flags & NHeader::NArcFlags::kNextCabinet) != 0; }
|
|
Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlock_AreaSize : 0); }
|
|
|
|
CArchInfo()
|
|
{
|
|
PerCabinet_AreaSize = 0;
|
|
PerFolder_AreaSize = 0;
|
|
PerDataBlock_AreaSize = 0;
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
PerCabinet_AreaSize = 0;
|
|
PerFolder_AreaSize = 0;
|
|
PerDataBlock_AreaSize = 0;
|
|
|
|
PrevArc.Clear();
|
|
NextArc.Clear();
|
|
}
|
|
};
|
|
|
|
|
|
struct CInArcInfo: public CArchInfo
|
|
{
|
|
UInt32 Size; // size of this cabinet file in bytes
|
|
UInt32 FileHeadersOffset; // offset of the first CFFILE entry
|
|
|
|
bool Parse(const Byte *p);
|
|
};
|
|
|
|
|
|
struct CDatabase
|
|
{
|
|
CRecordVector<CFolder> Folders;
|
|
CObjectVector<CItem> Items;
|
|
UInt64 StartPosition;
|
|
CInArcInfo ArcInfo;
|
|
|
|
void Clear()
|
|
{
|
|
ArcInfo.Clear();
|
|
Folders.Clear();
|
|
Items.Clear();
|
|
}
|
|
|
|
bool IsTherePrevFolder() const
|
|
{
|
|
FOR_VECTOR (i, Items)
|
|
if (Items[i].ContinuedFromPrev())
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
int GetNumberOfNewFolders() const
|
|
{
|
|
int res = Folders.Size();
|
|
if (IsTherePrevFolder())
|
|
res--;
|
|
return res;
|
|
}
|
|
};
|
|
|
|
|
|
struct CDatabaseEx: public CDatabase
|
|
{
|
|
CMyComPtr<IInStream> Stream;
|
|
};
|
|
|
|
|
|
struct CMvItem
|
|
{
|
|
unsigned VolumeIndex;
|
|
unsigned ItemIndex;
|
|
};
|
|
|
|
|
|
class CMvDatabaseEx
|
|
{
|
|
bool AreItemsEqual(unsigned i1, unsigned i2);
|
|
|
|
public:
|
|
CObjectVector<CDatabaseEx> Volumes;
|
|
CRecordVector<CMvItem> Items;
|
|
CRecordVector<int> StartFolderOfVol; // can be negative
|
|
CRecordVector<unsigned> FolderStartFileIndex;
|
|
|
|
int GetFolderIndex(const CMvItem *mvi) const
|
|
{
|
|
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
|
|
return StartFolderOfVol[mvi->VolumeIndex] +
|
|
db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size());
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
Volumes.Clear();
|
|
Items.Clear();
|
|
StartFolderOfVol.Clear();
|
|
FolderStartFileIndex.Clear();
|
|
}
|
|
|
|
void FillSortAndShrink();
|
|
bool Check();
|
|
};
|
|
|
|
|
|
class CInArchive
|
|
{
|
|
CInBufferBase _inBuffer;
|
|
CByteBuffer _tempBuf;
|
|
|
|
void Skip(unsigned size);
|
|
void Read(Byte *data, unsigned size);
|
|
void ReadName(AString &s);
|
|
void ReadOtherArc(COtherArc &oa);
|
|
HRESULT Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);
|
|
|
|
public:
|
|
bool IsArc;
|
|
bool ErrorInNames;
|
|
bool UnexpectedEnd;
|
|
bool HeaderError;
|
|
|
|
HRESULT Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);
|
|
};
|
|
|
|
}}
|
|
|
|
#endif
|