This commit is contained in:
Igor Pavlov
2014-11-23 00:00:00 +00:00
committed by Kornel Lesiński
parent 83f8ddcc5b
commit f08f4dcc3c
1158 changed files with 76451 additions and 35082 deletions

121
CPP/7zip/Archive/Cab/CabIn.h Executable file → Normal file
View File

@@ -3,96 +3,88 @@
#ifndef __ARCHIVE_CAB_IN_H
#define __ARCHIVE_CAB_IN_H
#include "../../IStream.h"
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyCom.h"
#include "../../Common/InBuffer.h"
#include "CabHeader.h"
#include "CabItem.h"
namespace NArchive {
namespace NCab {
class CInArchiveException
{
public:
enum CCauseType
{
kUnexpectedEndOfArchive = 0,
kIncorrectArchive,
kUnsupported
} Cause;
CInArchiveException(CCauseType cause) : Cause(cause) {}
};
struct COtherArchive
struct COtherArc
{
AString FileName;
AString DiskName;
};
struct CArchiveInfo
struct CArchInfo
{
Byte VersionMinor; /* cabinet file format version, minor */
Byte VersionMajor; /* cabinet file format version, major */
UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */
UInt16 NumFiles; /* number of CFFILE entries in this cabinet */
UInt16 Flags; /* cabinet file option indicators */
UInt16 SetID; /* must be the same for all cabinets in a set */
UInt16 CabinetNumber; /* number of this cabinet file in a set */
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
bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; }
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
bool IsTherePrev() const { return (Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0; }
bool IsThereNext() const { return (Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0; }
COtherArc PrevArc; // prev link can skip some volumes !!!
COtherArc NextArc;
UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area
Byte PerFolderAreaSize; // (optional) size of per-folder reserved area
Byte PerDataBlockAreaSize; // (optional) size of per-datablock reserved area
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); }
Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); }
COtherArchive PrevArc;
COtherArchive NextArc;
CArchiveInfo()
CArchInfo()
{
Clear();
}
void Clear()
{
PerCabinetAreaSize = 0;
PerFolderAreaSize = 0;
PerDataBlockAreaSize = 0;
PerCabinet_AreaSize = 0;
PerFolder_AreaSize = 0;
PerDataBlock_AreaSize = 0;
}
};
struct CInArchiveInfo: public CArchiveInfo
struct CInArcInfo: public CArchInfo
{
UInt32 Size; /* size of this cabinet file in bytes */
UInt32 Size; // size of this cabinet file in bytes
UInt32 FileHeadersOffset; // offset of the first CFFILE entry
bool Parse(const Byte *p);
};
struct CDatabase
{
UInt64 StartPosition;
CInArchiveInfo ArchiveInfo;
CObjectVector<CFolder> Folders;
CRecordVector<CFolder> Folders;
CObjectVector<CItem> Items;
UInt64 StartPosition;
CInArcInfo ArcInfo;
void Clear()
{
ArchiveInfo.Clear();
ArcInfo.Clear();
Folders.Clear();
Items.Clear();
}
bool IsTherePrevFolder() const
{
for (int i = 0; i < Items.Size(); i++)
FOR_VECTOR (i, Items)
if (Items[i].ContinuedFromPrev())
return true;
return false;
}
int GetNumberOfNewFolders() const
{
int res = Folders.Size();
@@ -100,8 +92,6 @@ struct CDatabase
res--;
return res;
}
UInt32 GetFileOffset(int index) const { return Items[index].Offset; }
UInt32 GetFileSize(int index) const { return Items[index].Size; }
};
struct CDatabaseEx: public CDatabase
@@ -111,25 +101,27 @@ struct CDatabaseEx: public CDatabase
struct CMvItem
{
int VolumeIndex;
int ItemIndex;
unsigned VolumeIndex;
unsigned ItemIndex;
};
class CMvDatabaseEx
{
bool AreItemsEqual(int i1, int i2);
bool AreItemsEqual(unsigned i1, unsigned i2);
public:
CObjectVector<CDatabaseEx> Volumes;
CRecordVector<CMvItem> Items;
CRecordVector<int> StartFolderOfVol;
CRecordVector<int> FolderStartFileIndex;
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();
@@ -137,23 +129,30 @@ public:
StartFolderOfVol.Clear();
FolderStartFileIndex.Clear();
}
void FillSortAndShrink();
bool Check();
};
class CInArchive
{
CInBuffer inBuffer;
CInBufferBase _inBuffer;
CByteBuffer _tempBuf;
Byte Read8();
UInt16 Read16();
UInt32 Read32();
AString SafeReadName();
void Skip(UInt32 size);
void ReadOtherArchive(COtherArchive &oa);
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:
HRESULT Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db);
bool IsArc;
bool ErrorInNames;
bool UnexpectedEnd;
bool HeaderError;
HRESULT Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);
};
}}