Use FResourceFile directly for the simple container types.

Instead let FResourceFile provide an interface for ad-hoc construction of a new container.
This commit is contained in:
Christoph Oelckers 2023-12-13 16:59:39 +01:00
parent 72a2e5d532
commit 6f8c3c60c4
9 changed files with 84 additions and 234 deletions

View file

@ -108,6 +108,12 @@ struct FResourceEntry
class FResourceFile
{
public:
FResourceFile(const char* filename, StringPool* sp);
FResourceFile(const char* filename, FileReader& r, StringPool* sp);
const char* NormalizeFileName(const char* fn, int fallbackcp = 0);
FResourceEntry* AllocateEntries(int count);
void GenerateHash();
void PostProcessArchive(LumpFilterInfo* filter);
protected:
FileReader Reader;
const char* FileName;
@ -116,15 +122,7 @@ protected:
char Hash[48];
StringPool* stringpool;
FResourceFile(const char *filename, StringPool* sp);
FResourceFile(const char *filename, FileReader &r, StringPool* sp);
const char* NormalizeFileName(const char* fn, int fallbackcp = 0);
void AllocateEntries(int count);
// for archives that can contain directories
void GenerateHash();
void PostProcessArchive(LumpFilterInfo *filter);
virtual void SetEntryAddress(uint32_t entry)
{
Entries[entry].Flags &= ~RESFF_NEEDFILESTART;

View file

@ -65,47 +65,23 @@ struct GrpLump
};
//==========================================================================
//
// Build GRP file
//
//==========================================================================
class FGrpFile : public FResourceFile
{
public:
FGrpFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(LumpFilterInfo* filter);
};
//==========================================================================
//
// Initializes a Build GRP file
//
//==========================================================================
FGrpFile::FGrpFile(const char *filename, FileReader &file, StringPool* sp)
: FResourceFile(filename, file, sp)
{
}
//==========================================================================
//
// Open it
//
//==========================================================================
bool FGrpFile::Open(LumpFilterInfo* filter)
static bool OpenGrp(FResourceFile* file, LumpFilterInfo* filter)
{
GrpHeader header;
Reader.Read(&header, sizeof(header));
AllocateEntries(header.NumLumps);
NumLumps = LittleLong(header.NumLumps);
auto Reader = file->GetContainerReader();
Reader->Read(&header, sizeof(header));
uint32_t NumLumps = LittleLong(header.NumLumps);
auto Entries = file->AllocateEntries(NumLumps);
GrpLump *fileinfo = new GrpLump[NumLumps];
Reader.Read (fileinfo, NumLumps * sizeof(GrpLump));
Reader->Read (fileinfo, NumLumps * sizeof(GrpLump));
int Position = sizeof(GrpHeader) + NumLumps * sizeof(GrpLump);
@ -119,9 +95,9 @@ bool FGrpFile::Open(LumpFilterInfo* filter)
fileinfo[i].NameWithZero[12] = '\0'; // Be sure filename is null-terminated
Entries[i].ResourceID = -1;
Entries[i].Method = METHOD_STORED;
Entries[i].FileName = NormalizeFileName(fileinfo[i].Name);
Entries[i].FileName = file->NormalizeFileName(fileinfo[i].Name);
}
GenerateHash();
file->GenerateHash();
delete[] fileinfo;
return true;
}
@ -144,12 +120,12 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo*
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "KenSilverman", 12))
{
auto rf = new FGrpFile(filename, file, sp);
if (rf->Open(filter)) return rf;
auto rf = new FResourceFile(filename, file, sp);
if (OpenGrp(rf, filter)) return rf;
file = rf->Destroy();
}
}
return NULL;
return nullptr;
}
}

View file

@ -35,48 +35,22 @@
#include "resourcefile.h"
namespace FileSys {
//==========================================================================
//
// Single lump
//
//==========================================================================
class FLumpFile : public FResourceFile
{
public:
FLumpFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(LumpFilterInfo* filter);
};
//==========================================================================
//
// FLumpFile::FLumpFile
//
//==========================================================================
FLumpFile::FLumpFile(const char *filename, FileReader &file, StringPool* sp)
: FResourceFile(filename, file, sp)
{
}
//==========================================================================
//
// Open it
//
//==========================================================================
bool FLumpFile::Open(LumpFilterInfo*)
static bool OpenLump(FResourceFile* file, LumpFilterInfo*)
{
AllocateEntries(1);
Entries[0].FileName = NormalizeFileName(ExtractBaseName(FileName, true).c_str());
auto Entries = file->AllocateEntries(1);
Entries[0].FileName = file->NormalizeFileName(ExtractBaseName(file->GetFileName(), true).c_str());
Entries[0].Namespace = ns_global;
Entries[0].ResourceID = -1;
Entries[0].Position = 0;
Entries[0].Length = Reader.GetLength();
Entries[0].Length = file->GetContainerReader()->GetLength();
Entries[0].Method = METHOD_STORED;
Entries[0].Flags = 0;
NumLumps = 1;
return true;
}
@ -89,8 +63,8 @@ bool FLumpFile::Open(LumpFilterInfo*)
FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
// always succeeds
auto rf = new FLumpFile(filename, file, sp);
if (rf->Open(filter)) return rf;
auto rf = new FResourceFile(filename, file, sp);
if (OpenLump(rf, filter)) return rf;
file = rf->Destroy();
return NULL;
}

View file

@ -57,51 +57,25 @@ struct dpackheader_t
} ;
//==========================================================================
//
// Wad file
//
//==========================================================================
class FPakFile : public FResourceFile
{
public:
FPakFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(LumpFilterInfo* filter);
};
//==========================================================================
//
// FWadFile::FWadFile
//
// Initializes a WAD file
//
//==========================================================================
FPakFile::FPakFile(const char *filename, FileReader &file, StringPool* sp)
: FResourceFile(filename, file, sp)
{
}
//==========================================================================
//
// Open it
//
//==========================================================================
bool FPakFile::Open(LumpFilterInfo* filter)
static bool OpenPak(FResourceFile* file, LumpFilterInfo* filter)
{
dpackheader_t header;
Reader.Read(&header, sizeof(header));
AllocateEntries(header.dirlen / sizeof(dpackfile_t));
NumLumps = LittleLong(header.dirlen) / sizeof(dpackfile_t);
auto Reader = file->GetContainerReader();
Reader->Read(&header, sizeof(header));
uint32_t NumLumps = header.dirlen / sizeof(dpackfile_t);
auto Entries = file->AllocateEntries(NumLumps);
header.dirofs = LittleLong(header.dirofs);
TArray<dpackfile_t> fileinfo(NumLumps, true);
Reader.Seek (header.dirofs, FileReader::SeekSet);
Reader.Read (fileinfo.Data(), NumLumps * sizeof(dpackfile_t));
Reader->Seek (header.dirofs, FileReader::SeekSet);
Reader->Read (fileinfo.Data(), NumLumps * sizeof(dpackfile_t));
for(uint32_t i = 0; i < NumLumps; i++)
{
@ -111,10 +85,10 @@ bool FPakFile::Open(LumpFilterInfo* filter)
Entries[i].Namespace = ns_global;
Entries[i].ResourceID = -1;
Entries[i].Method = METHOD_STORED;
Entries[i].FileName = NormalizeFileName(fileinfo[i].name);
Entries[i].FileName = file->NormalizeFileName(fileinfo[i].name);
}
GenerateHash();
PostProcessArchive(filter);
file->GenerateHash();
file->PostProcessArchive(filter);
return true;
}
@ -136,8 +110,8 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo*
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "PACK", 4))
{
auto rf = new FPakFile(filename, file, sp);
if (rf->Open(filter)) return rf;
auto rf = new FResourceFile(filename, file, sp);
if (OpenPak(rf, filter)) return rf;
file = rf->Destroy();
}
}

View file

@ -84,52 +84,27 @@ void BloodCrypt (void *data, int key, int len)
}
//==========================================================================
//
// Blood RFF file
//
//==========================================================================
class FRFFFile : public FResourceFile
{
public:
FRFFFile(const char * filename, FileReader &file, StringPool* sp);
virtual bool Open(LumpFilterInfo* filter);
};
//==========================================================================
//
// Initializes a Blood RFF file
//
//==========================================================================
FRFFFile::FRFFFile(const char *filename, FileReader &file, StringPool* sp)
: FResourceFile(filename, file, sp)
{
}
//==========================================================================
//
// Initializes a Blood RFF file
//
//==========================================================================
bool FRFFFile::Open(LumpFilterInfo*)
static bool OpenRFF(FResourceFile* file, LumpFilterInfo*)
{
RFFLump *lumps;
RFFInfo header;
Reader.Read(&header, sizeof(header));
auto Reader = file->GetContainerReader();
Reader->Read(&header, sizeof(header));
AllocateEntries(LittleLong(header.NumLumps));
NumLumps = LittleLong(header.NumLumps);
uint32_t NumLumps = LittleLong(header.NumLumps);
auto Entries = file->AllocateEntries(NumLumps);
header.DirOfs = LittleLong(header.DirOfs);
lumps = new RFFLump[header.NumLumps];
Reader.Seek (header.DirOfs, FileReader::SeekSet);
Reader.Read (lumps, header.NumLumps * sizeof(RFFLump));
BloodCrypt (lumps, header.DirOfs, header.NumLumps * sizeof(RFFLump));
Reader->Seek (LittleLong(header.DirOfs), FileReader::SeekSet);
Reader->Read (lumps, NumLumps * sizeof(RFFLump));
BloodCrypt (lumps, LittleLong(header.DirOfs), NumLumps * sizeof(RFFLump));
for (uint32_t i = 0; i < NumLumps; ++i)
{
@ -161,10 +136,10 @@ bool FRFFFile::Open(LumpFilterInfo*)
name[len+2] = lumps[i].Extension[1];
name[len+3] = lumps[i].Extension[2];
name[len+4] = 0;
Entries[i].FileName = NormalizeFileName(name);
Entries[i].FileName = file->NormalizeFileName(name);
}
delete[] lumps;
GenerateHash();
file->GenerateHash();
return true;
}
@ -185,8 +160,8 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo*
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "RFF\x1a", 4))
{
auto rf = new FRFFFile(filename, file, sp);
if (rf->Open(filter)) return rf;
auto rf = new FResourceFile(filename, file, sp);
if (OpenRFF(rf, filter)) return rf;
file = rf->Destroy();
}
}

View file

@ -36,30 +36,6 @@
#include "resourcefile.h"
namespace FileSys {
//==========================================================================
//
// Build GRP file
//
//==========================================================================
class FSSIFile : public FResourceFile
{
public:
FSSIFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(int version, int EntryCount, LumpFilterInfo* filter);
};
//==========================================================================
//
// Initializes a Build GRP file
//
//==========================================================================
FSSIFile::FSSIFile(const char *filename, FileReader &file, StringPool* sp)
: FResourceFile(filename, file, sp)
{
}
//==========================================================================
//
@ -68,22 +44,23 @@ FSSIFile::FSSIFile(const char *filename, FileReader &file, StringPool* sp)
//
//==========================================================================
bool FSSIFile::Open(int version, int EntryCount, LumpFilterInfo*)
static bool OpenSSI(FResourceFile* file, int version, int EntryCount, LumpFilterInfo*)
{
AllocateEntries(EntryCount*2);
NumLumps = EntryCount*2;
uint32_t NumLumps = EntryCount * 2;
auto Entries = file->AllocateEntries(NumLumps);
auto Reader = file->GetContainerReader();
int32_t j = (version == 2 ? 267 : 254) + (EntryCount * 121);
for (uint32_t i = 0; i < NumLumps; i+=2)
{
char fn[13];
int strlength = Reader.ReadUInt8();
int strlength = Reader->ReadUInt8();
if (strlength > 12) strlength = 12;
Reader.Read(fn, 12);
Reader->Read(fn, 12);
fn[strlength] = 0;
int flength = Reader.ReadInt32();
int flength = Reader->ReadInt32();
Entries[i].Position = j;
Entries[i].Length = flength;
@ -91,7 +68,7 @@ bool FSSIFile::Open(int version, int EntryCount, LumpFilterInfo*)
Entries[i].Namespace = ns_global;
Entries[i].Method = METHOD_STORED;
Entries[i].ResourceID = -1;
Entries[i].FileName = NormalizeFileName(fn);
Entries[i].FileName = file->NormalizeFileName(fn);
if (strstr(fn, ".GRP")) Entries[i].Flags |= RESFF_EMBEDDED;
// SSI files can swap the order of the extension's characters - but there's no reliable detection for this and it can be mixed inside the same container,
@ -103,13 +80,14 @@ bool FSSIFile::Open(int version, int EntryCount, LumpFilterInfo*)
Entries[i + 1].Flags = 0;
Entries[i + 1].Namespace = ns_global;
Entries[i + 1].ResourceID = -1;
Entries[i + 1].FileName = NormalizeFileName(fn);
Entries[i + 1].FileName = file->NormalizeFileName(fn);
Entries[i + 1].Method = METHOD_STORED;
if (strstr(fn, ".GRP")) Entries[i + 1].Flags |= RESFF_EMBEDDED;
j += flength;
Reader.Seek(104, FileReader::SeekCur);
Reader->Seek(104, FileReader::SeekCur);
file->GenerateHash();
}
return true;
}
@ -151,8 +129,8 @@ FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo*
{
if (!skipstring(70)) return nullptr;
}
auto ssi = new FSSIFile(filename, file, sp);
if (ssi->Open(version, numfiles, filter)) return ssi;
auto ssi = new FResourceFile(filename, file, sp);
if (OpenSSI(ssi, version, numfiles, filter)) return ssi;
file = ssi->Destroy();
}
}

View file

@ -41,45 +41,20 @@
namespace FileSys {
using namespace byteswap;
//==========================================================================
//
// WH resource file
//
//==========================================================================
class FWHResFile : public FResourceFile
{
const char* BaseName;
public:
FWHResFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(LumpFilterInfo* filter);
};
//==========================================================================
//
//
//
//==========================================================================
FWHResFile::FWHResFile(const char *filename, FileReader &file, StringPool* sp)
: FResourceFile(filename, file, sp)
{
BaseName = stringpool->Strdup(ExtractBaseName(filename, false).c_str());
}
//==========================================================================
//
// Open it
//
//==========================================================================
bool FWHResFile::Open(LumpFilterInfo*)
bool OpenWHRes(FResourceFile* file, LumpFilterInfo*)
{
uint32_t directory[1024];
Reader.Seek(-4096, FileReader::SeekEnd);
Reader.Read(directory, 4096);
auto BaseName = ExtractBaseName(file->GetFileName());
auto Reader = file->GetContainerReader();
Reader->Seek(-4096, FileReader::SeekEnd);
Reader->Read(directory, 4096);
int nl =1024/3;
@ -93,8 +68,8 @@ bool FWHResFile::Open(LumpFilterInfo*)
break;
}
}
AllocateEntries(k);
NumLumps = k;
auto Entries = file->AllocateEntries(k);
auto NumLumps = k;
int i = 0;
for(k = 0; k < NumLumps; k++)
@ -103,8 +78,7 @@ bool FWHResFile::Open(LumpFilterInfo*)
uint32_t length = LittleLong(directory[k*3+1]);
char num[6];
snprintf(num, 6, "/%04d", k);
std::string synthname = BaseName;
synthname += num;
std::string synthname = BaseName + num;
Entries[i].Position = offset;
Entries[i].Length = length;
@ -112,7 +86,7 @@ bool FWHResFile::Open(LumpFilterInfo*)
Entries[i].Namespace = ns_global;
Entries[i].ResourceID = -1;
Entries[i].Method = METHOD_STORED;
Entries[i].FileName = NormalizeFileName(synthname.c_str());
Entries[i].FileName = file->NormalizeFileName(synthname.c_str());
i++;
}
return true;
@ -145,8 +119,8 @@ FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo
if (offset != checkpos || length == 0 || offset + length >= (size_t)size - 4096 ) return nullptr;
checkpos += (length+4095) / 4096;
}
auto rf = new FWHResFile(filename, file, sp);
if (rf->Open(filter)) return rf;
auto rf = new FResourceFile(filename, file, sp);
if (OpenWHRes(rf, filter)) return rf;
file = rf->Destroy();
}
return NULL;

View file

@ -298,22 +298,22 @@ bool FileSystem::InitMultipleFiles (std::vector<std::string>& filenames, LumpFil
//
//==========================================================================
FResourceFile* CheckLump(const char* filename, FileReader& file, LumpFilterInfo*, FileSystemMessageFunc Printf, StringPool* sp);
int FileSystem::AddFromBuffer(const char* name, char* data, int size, int id, int flags)
{
FileReader fr;
fr.OpenMemoryArray((uint8_t*)data, size);
// just wrap this into a single lump resource file (should be done a little better later.)
auto rf = CheckLump(name, fr, nullptr, nullptr, stringpool);
if (rf)
{
Files.push_back(rf);
FileInfo.resize(FileInfo.size() + 1);
FileSystem::LumpRecord* lump_p = &FileInfo.back();
lump_p->SetFromLump(rf, 0, (int)Files.size() - 1, stringpool);
}
// wrap this into a single lump resource file (should be done a little better later.)
auto rf = new FResourceFile(name, fr, stringpool);
auto Entries = rf->AllocateEntries(1);
Entries[0].FileName = rf->NormalizeFileName(ExtractBaseName(name, true).c_str());
Entries[0].ResourceID = -1;
Entries[0].Length = size;
Files.push_back(rf);
FileInfo.resize(FileInfo.size() + 1);
FileSystem::LumpRecord* lump_p = &FileInfo.back();
lump_p->SetFromLump(rf, 0, (int)Files.size() - 1, stringpool);
return (int)FileInfo.size() - 1;
}

View file

@ -270,11 +270,12 @@ const char* FResourceFile::NormalizeFileName(const char* fn, int fallbackcp)
//
//==========================================================================
void FResourceFile::AllocateEntries(int count)
FResourceEntry* FResourceFile::AllocateEntries(int count)
{
NumLumps = count;
Entries = (FResourceEntry*)stringpool->Alloc(count * sizeof(FResourceEntry));
memset(Entries, 0, count * sizeof(FResourceEntry));
return Entries;
}