- use a string pool to store the filenames in FResourceLump.

This commit is contained in:
Christoph Oelckers 2023-08-22 00:56:31 +02:00
parent 4f8305de5f
commit 3d673e3f20
17 changed files with 137 additions and 119 deletions

View File

@ -186,7 +186,7 @@ class F7ZFile : public FResourceFile
C7zArchive *Archive;
public:
F7ZFile(const char * filename, FileReader &filer);
F7ZFile(const char * filename, FileReader &filer, StringPool* sp);
bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf);
virtual ~F7ZFile();
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
@ -200,8 +200,8 @@ public:
//
//==========================================================================
F7ZFile::F7ZFile(const char * filename, FileReader &filer)
: FResourceFile(filename, filer)
F7ZFile::F7ZFile(const char * filename, FileReader &filer, StringPool* sp)
: FResourceFile(filename, filer, sp)
{
Lumps = NULL;
Archive = NULL;
@ -280,7 +280,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf)
}
FixPathSeparator(&nameASCII.front());
lump_p->LumpNameSetup(nameASCII.c_str());
lump_p->LumpNameSetup(nameASCII.c_str(), stringpool);
lump_p->LumpSize = static_cast<int>(SzArEx_GetFileSize(archPtr, i));
lump_p->Owner = this;
lump_p->Flags = LUMPF_FULLPATH|LUMPF_COMPRESSED;
@ -352,7 +352,7 @@ int F7ZLump::FillCache()
//
//==========================================================================
FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
char head[k7zSignatureSize];
@ -363,7 +363,7 @@ FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* f
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, k7zSignature, k7zSignatureSize))
{
auto rf = new F7ZFile(filename, file);
auto rf = new F7ZFile(filename, file, sp);
if (rf->Open(filter, Printf)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View File

@ -75,7 +75,7 @@ class FDirectory : public FResourceFile
void AddEntry(const char *fullpath, int size);
public:
FDirectory(const char * dirname, bool nosubdirflag = false);
FDirectory(const char * dirname, StringPool* sp, bool nosubdirflag = false);
bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
};
@ -88,8 +88,8 @@ public:
//
//==========================================================================
FDirectory::FDirectory(const char * directory, bool nosubdirflag)
: FResourceFile(""), nosubdir(nosubdirflag)
FDirectory::FDirectory(const char * directory, StringPool* sp, bool nosubdirflag)
: FResourceFile("", sp), nosubdir(nosubdirflag)
{
FileName = FS_FullPath(directory);
if (FileName[FileName.length()-1] != '/') FileName += '/';
@ -171,7 +171,7 @@ void FDirectory::AddEntry(const char *fullpath, int size)
for (auto& c : name) c = tolower(c);
// The lump's name is only the part relative to the main directory
lump_p->LumpNameSetup(name.c_str());
lump_p->LumpNameSetup(name.c_str(), stringpool);
lump_p->LumpSize = size;
lump_p->Owner = this;
lump_p->Flags = 0;
@ -221,9 +221,9 @@ int FDirectoryLump::FillCache()
//
//==========================================================================
FResourceFile *CheckDir(const char *filename, bool nosubdirflag, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *CheckDir(const char *filename, bool nosubdirflag, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
auto rf = new FDirectory(filename, nosubdirflag);
auto rf = new FDirectory(filename, sp, nosubdirflag);
if (rf->Open(filter, Printf)) return rf;
delete rf;
return nullptr;

View File

@ -73,7 +73,7 @@ struct GrpLump
class FGrpFile : public FUncompressedFile
{
public:
FGrpFile(const char * filename, FileReader &file);
FGrpFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(LumpFilterInfo* filter);
};
@ -84,8 +84,8 @@ public:
//
//==========================================================================
FGrpFile::FGrpFile(const char *filename, FileReader &file)
: FUncompressedFile(filename, file)
FGrpFile::FGrpFile(const char *filename, FileReader &file, StringPool* sp)
: FUncompressedFile(filename, file, sp)
{
}
@ -117,7 +117,7 @@ bool FGrpFile::Open(LumpFilterInfo* filter)
Position += fileinfo[i].Size;
Lumps[i].Flags = 0;
fileinfo[i].NameWithZero[12] = '\0'; // Be sure filename is null-terminated
Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero);
Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero, stringpool);
}
GenerateHash();
delete[] fileinfo;
@ -131,7 +131,7 @@ bool FGrpFile::Open(LumpFilterInfo* filter)
//
//==========================================================================
FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
char head[12];
@ -142,7 +142,7 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo*
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "KenSilverman", 12))
{
auto rf = new FGrpFile(filename, file);
auto rf = new FGrpFile(filename, file, sp);
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View File

@ -43,7 +43,7 @@
class FLumpFile : public FUncompressedFile
{
public:
FLumpFile(const char * filename, FileReader &file);
FLumpFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(LumpFilterInfo* filter);
};
@ -54,8 +54,8 @@ public:
//
//==========================================================================
FLumpFile::FLumpFile(const char *filename, FileReader &file)
: FUncompressedFile(filename, file)
FLumpFile::FLumpFile(const char *filename, FileReader &file, StringPool* sp)
: FUncompressedFile(filename, file, sp)
{
}
@ -68,7 +68,7 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file)
bool FLumpFile::Open(LumpFilterInfo*)
{
Lumps.Resize(1);
Lumps[0].LumpNameSetup(ExtractBaseName(FileName.c_str(), true).c_str());
Lumps[0].LumpNameSetup(ExtractBaseName(FileName.c_str(), true).c_str(), stringpool);
Lumps[0].Owner = this;
Lumps[0].Position = 0;
Lumps[0].LumpSize = (int)Reader.GetLength();
@ -83,10 +83,10 @@ bool FLumpFile::Open(LumpFilterInfo*)
//
//==========================================================================
FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
// always succeeds
auto rf = new FLumpFile(filename, file);
auto rf = new FLumpFile(filename, file, sp);
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View File

@ -65,7 +65,7 @@ struct dpackheader_t
class FPakFile : public FUncompressedFile
{
public:
FPakFile(const char * filename, FileReader &file);
FPakFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(LumpFilterInfo* filter);
};
@ -78,8 +78,8 @@ public:
//
//==========================================================================
FPakFile::FPakFile(const char *filename, FileReader &file)
: FUncompressedFile(filename, file)
FPakFile::FPakFile(const char *filename, FileReader &file, StringPool* sp)
: FUncompressedFile(filename, file, sp)
{
}
@ -105,7 +105,7 @@ bool FPakFile::Open(LumpFilterInfo* filter)
for(uint32_t i = 0; i < NumLumps; i++)
{
Lumps[i].LumpNameSetup(fileinfo[i].name);
Lumps[i].LumpNameSetup(fileinfo[i].name, stringpool);
Lumps[i].Flags = LUMPF_FULLPATH;
Lumps[i].Owner = this;
Lumps[i].Position = LittleLong(fileinfo[i].filepos);
@ -124,7 +124,7 @@ bool FPakFile::Open(LumpFilterInfo* filter)
//
//==========================================================================
FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
char head[4];
@ -135,7 +135,7 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo*
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "PACK", 4))
{
auto rf = new FPakFile(filename, file);
auto rf = new FPakFile(filename, file, sp);
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View File

@ -110,7 +110,7 @@ class FRFFFile : public FResourceFile
FRFFLump *Lumps;
public:
FRFFFile(const char * filename, FileReader &file);
FRFFFile(const char * filename, FileReader &file, StringPool* sp);
virtual ~FRFFFile();
virtual bool Open(LumpFilterInfo* filter);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
@ -123,8 +123,8 @@ public:
//
//==========================================================================
FRFFFile::FRFFFile(const char *filename, FileReader &file)
: FResourceFile(filename, file)
FRFFFile::FRFFFile(const char *filename, FileReader &file, StringPool* sp)
: FResourceFile(filename, file, sp)
{
Lumps = NULL;
}
@ -172,7 +172,7 @@ bool FRFFFile::Open(LumpFilterInfo*)
name[len+2] = lumps[i].Extension[1];
name[len+3] = lumps[i].Extension[2];
name[len+4] = 0;
Lumps[i].LumpNameSetup(name);
Lumps[i].LumpNameSetup(name, stringpool);
}
delete[] lumps;
GenerateHash();
@ -238,7 +238,7 @@ int FRFFLump::FillCache()
//
//==========================================================================
FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
char head[4];
@ -249,7 +249,7 @@ 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);
auto rf = new FRFFFile(filename, file, sp);
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View File

@ -44,7 +44,7 @@
class FSSIFile : public FUncompressedFile
{
public:
FSSIFile(const char * filename, FileReader &file);
FSSIFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(int version, int lumpcount, LumpFilterInfo* filter);
};
@ -55,8 +55,8 @@ public:
//
//==========================================================================
FSSIFile::FSSIFile(const char *filename, FileReader &file)
: FUncompressedFile(filename, file)
FSSIFile::FSSIFile(const char *filename, FileReader &file, StringPool* sp)
: FUncompressedFile(filename, file, sp)
{
}
@ -85,7 +85,7 @@ bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*)
int flength = Reader.ReadInt32();
Lumps[i].LumpNameSetup(fn);
Lumps[i].LumpNameSetup(fn, stringpool);
Lumps[i].Position = j;
Lumps[i].LumpSize = flength;
Lumps[i].Owner = this;
@ -94,7 +94,7 @@ bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*)
// 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,
// so we have no choice but to create another file record for the altered name.
std::swap(fn[strlength - 1], fn[strlength - 3]);
Lumps[i+1].LumpNameSetup(fn);
Lumps[i+1].LumpNameSetup(fn, stringpool);
Lumps[i+1].Position = j;
Lumps[i+1].LumpSize = flength;
Lumps[i+1].Owner = this;
@ -114,7 +114,7 @@ bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*)
//
//==========================================================================
FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
char zerobuf[72];
char buf[72];
@ -144,7 +144,7 @@ FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo*
{
if (!skipstring(70)) return nullptr;
}
auto ssi = new FSSIFile(filename, file);
auto ssi = new FSSIFile(filename, file, sp);
if (ssi->Open(version, numfiles, filter)) return ssi;
file = std::move(ssi->Reader); // to avoid destruction of reader
delete ssi;

View File

@ -136,7 +136,7 @@ class FWadFile : public FResourceFile
void SkinHack (FileSystemMessageFunc Printf);
public:
FWadFile(const char * filename, FileReader &file);
FWadFile(const char * filename, FileReader &file, StringPool* sp);
FResourceLump *GetLump(int lump) { return &Lumps[lump]; }
bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf);
};
@ -150,8 +150,8 @@ public:
//
//==========================================================================
FWadFile::FWadFile(const char *filename, FileReader &file)
: FResourceFile(filename, file)
FWadFile::FWadFile(const char *filename, FileReader &file, StringPool* sp)
: FResourceFile(filename, file, sp)
{
}
@ -207,7 +207,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf)
#else
Lumps[i].Compressed = false;
#endif
Lumps[i].LumpNameSetup(n);
Lumps[i].LumpNameSetup(n, stringpool);
Lumps[i].Owner = this;
Lumps[i].Position = isBigEndian ? BigLong(fileinfo[i].FilePos) : LittleLong(fileinfo[i].FilePos);
@ -221,7 +221,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf)
if (Lumps[i].LumpSize != 0)
{
Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.c_str(), Lumps[i].getName());
Lumps[i].LumpNameSetup("");
Lumps[i].clearName();
}
Lumps[i].LumpSize = Lumps[i].Position = 0;
}
@ -420,7 +420,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf)
if (!strnicmp(lump->getName(), "S_SKIN", 6))
{ // Wad has at least one skin.
lump->LumpNameSetup("S_SKIN");
lump->LumpNameSetup("S_SKIN", nullptr);
if (!skinned)
{
skinned = true;
@ -464,7 +464,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf)
//
//==========================================================================
FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
char head[4];
@ -475,7 +475,7 @@ FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo*
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "IWAD", 4) || !memcmp(head, "PWAD", 4))
{
auto rf = new FWadFile(filename, file);
auto rf = new FWadFile(filename, file, sp);
if (rf->Open(filter, Printf)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View File

@ -49,7 +49,7 @@ class FWHResFile : public FUncompressedFile
{
std::string basename;
public:
FWHResFile(const char * filename, FileReader &file);
FWHResFile(const char * filename, FileReader &file, StringPool* sp);
bool Open(LumpFilterInfo* filter);
};
@ -60,8 +60,8 @@ public:
//
//==========================================================================
FWHResFile::FWHResFile(const char *filename, FileReader &file)
: FUncompressedFile(filename, file)
FWHResFile::FWHResFile(const char *filename, FileReader &file, StringPool* sp)
: FUncompressedFile(filename, file, sp)
{
basename = ExtractBaseName(filename, false);
}
@ -92,7 +92,7 @@ bool FWHResFile::Open(LumpFilterInfo*)
char num[5];
snprintf(num, 5, "/%04d", k);
std::string synthname = basename + num;
Lumps[i].LumpNameSetup(synthname.c_str());
Lumps[i].LumpNameSetup(synthname.c_str(), stringpool);
Lumps[i].Owner = this;
Lumps[i].Position = offset;
Lumps[i].LumpSize = length;
@ -111,7 +111,7 @@ bool FWHResFile::Open(LumpFilterInfo*)
//
//==========================================================================
FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
if (file.GetLength() >= 8192) // needs to be at least 8192 to contain one file and the directory.
{
@ -131,7 +131,7 @@ 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);
auto rf = new FWHResFile(filename, file, sp);
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View File

@ -164,8 +164,8 @@ static uint32_t Zip_FindCentralDir(FileReader &fin, bool* zip64)
//
//==========================================================================
FZipFile::FZipFile(const char * filename, FileReader &file)
: FResourceFile(filename, file)
FZipFile::FZipFile(const char * filename, FileReader &file, StringPool* sp)
: FResourceFile(filename, file, sp)
{
Lumps = NULL;
}
@ -396,7 +396,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf)
}
}
lump_p->LumpNameSetup(name.c_str());
lump_p->LumpNameSetup(name.c_str(), stringpool);
lump_p->LumpSize = UncompressedSize;
lump_p->Owner = this;
// The start of the Reader will be determined the first time it is accessed.
@ -532,7 +532,7 @@ int FZipLump::GetFileOffset()
//
//==========================================================================
FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
char head[4];
@ -543,7 +543,7 @@ FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo*
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "PK\x3\x4", 4))
{
auto rf = new FZipFile(filename, file);
auto rf = new FZipFile(filename, file, sp);
if (rf->Open(filter, Printf)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View File

@ -39,7 +39,7 @@ class FZipFile : public FResourceFile
FZipLump *Lumps;
public:
FZipFile(const char * filename, FileReader &file);
FZipFile(const char * filename, FileReader &file, StringPool* sp);
virtual ~FZipFile();
bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }

View File

@ -44,6 +44,7 @@
#include "filesystem.h"
#include "fs_findfile.h"
#include "md5.hpp"
#include "fs_stringpool.h"
// MACROS ------------------------------------------------------------------
@ -191,7 +192,8 @@ FileSystem fileSystem;
FileSystem::FileSystem()
{
// Cannot be defaulted! This is needed to initialize the LumpRecord array, which depends on data only available here.
stringpool = new StringPool;
stringpool->shared = true; // will be used by all owned resource files.
}
FileSystem::~FileSystem ()
@ -323,7 +325,7 @@ int FileSystem::AddFromBuffer(const char* name, const char* type, char* data, in
fullname += ':';
fullname += type;
auto newlump = new FMemoryLump(data, size);
newlump->LumpNameSetup(fullname.c_str());
newlump->LumpNameSetup(fullname.c_str(), stringpool);
AddLump(newlump);
FileInfo.back().resourceId = id;
return (int)FileInfo.size()-1;
@ -379,9 +381,9 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf
if (!isdir)
resfile = FResourceFile::OpenResourceFile(filename, filereader, false, filter, Printf);
resfile = FResourceFile::OpenResourceFile(filename, filereader, false, filter, Printf, stringpool);
else
resfile = FResourceFile::OpenDirectory(filename, filter, Printf);
resfile = FResourceFile::OpenDirectory(filename, filter, Printf, stringpool);
if (resfile != NULL)
{
@ -943,7 +945,7 @@ void FileSystem::MoveLumpsInFolder(const char *path)
FileInfo.push_back(li);
li.lump = &placeholderLump; // Make the old entry point to something empty. We cannot delete the lump record here because it'd require adjustment of all indices in the list.
auto &ln = FileInfo.back();
ln.lump->LumpNameSetup(ln.longName.c_str() + len);
ln.lump->LumpNameSetup(ln.longName.c_str() + len, stringpool); // may be able to avoid the string allocation!
ln.SetFromLump(rfnum, ln.lump);
}
}

View File

@ -204,6 +204,8 @@ protected:
int IwadIndex = -1;
int MaxIwadIndex = -1;
StringPool* stringpool;
private:
void DeleteAll();
void MoveLumpsInFolder(const char *);

View File

@ -120,7 +120,7 @@ void *StringPool::iAlloc(size_t size)
const char* StringPool::Strdup(const char* str)
{
char* p = (char*)iAlloc((strlen(str) + 15) & ~15 );
char* p = (char*)iAlloc((strlen(str) + 8) & ~7 );
strcpy(p, str);
return p;
}

View File

@ -3,8 +3,12 @@
// Storage for all the static strings the file system must hold.
class StringPool
{
public:
// do not allow externally defining this.
friend class FileSystem;
friend class FResourceFile;
private:
StringPool(size_t blocksize = 10*1024) : TopBlock(nullptr), FreeBlocks(nullptr), BlockSize(blocksize) {}
public:
~StringPool();
const char* Strdup(const char*);

View File

@ -37,6 +37,7 @@
#include <zlib.h>
#include "resourcefile.h"
#include "md5.hpp"
#include "fs_stringpool.h"
std::string ExtractBaseName(const char* path, bool include_extension)
{
@ -122,13 +123,17 @@ FResourceLump::~FResourceLump()
//
//==========================================================================
void FResourceLump::LumpNameSetup(const char *iname)
void FResourceLump::LumpNameSetup(const char *iname, StringPool* allocator)
{
// this causes interference with real Dehacked lumps.
if (!stricmp(iname, "dehacked.exe"))
{
iname = "";
}
else if (allocator)
{
iname = allocator->Strdup(iname);
}
FullName = iname;
}
@ -159,14 +164,14 @@ static bool IsWadInFolder(const FResourceFile* const archive, const char* const
void FResourceLump::CheckEmbedded(LumpFilterInfo* lfi)
{
// Checks for embedded archives
const char *c = strstr(FullName.c_str(), ".wad");
if (c && strlen(c) == 4 && (!strchr(FullName.c_str(), '/') || IsWadInFolder(Owner, FullName.c_str())))
const char *c = strstr(FullName, ".wad");
if (c && strlen(c) == 4 && (!strchr(FullName, '/') || IsWadInFolder(Owner, FullName)))
{
Flags |= LUMPF_EMBEDDED;
}
else if (lfi) for (auto& fstr : lfi->embeddings)
{
if (!stricmp(FullName.c_str(), fstr.c_str()))
if (!stricmp(FullName, fstr.c_str()))
{
Flags |= LUMPF_EMBEDDED;
}
@ -265,18 +270,18 @@ int FResourceLump::Unlock()
//
//==========================================================================
typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile* CheckWHRes(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckLump(const char *filename,FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckDir(const char *filename, bool nosub, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile* CheckWHRes(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile *CheckLump(const char *filename,FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
FResourceFile *CheckDir(const char *filename, bool nosub, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckSSI, CheckWHRes, CheckLump };
@ -285,35 +290,35 @@ static int nulPrintf(FSMessageLevel msg, const char* fmt, ...)
return 0;
}
FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
if (Printf == nullptr) Printf = nulPrintf;
for(auto func : funcs)
{
if (containeronly && func == CheckLump) break;
FResourceFile *resfile = func(filename, file, filter, Printf);
FResourceFile *resfile = func(filename, file, filter, Printf, sp);
if (resfile != NULL) return resfile;
}
return NULL;
}
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
return DoOpenResourceFile(filename, file, containeronly, filter, Printf);
return DoOpenResourceFile(filename, file, containeronly, filter, Printf, sp);
}
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
FileReader file;
if (!file.OpenFile(filename)) return nullptr;
return DoOpenResourceFile(filename, file, containeronly, filter, Printf);
return DoOpenResourceFile(filename, file, containeronly, filter, Printf, sp);
}
FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp)
{
if (Printf == nullptr) Printf = nulPrintf;
return CheckDir(filename, false, filter, Printf);
return CheckDir(filename, false, filter, Printf, sp);
}
//==========================================================================
@ -322,19 +327,21 @@ FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo
//
//==========================================================================
FResourceFile::FResourceFile(const char *filename)
FResourceFile::FResourceFile(const char *filename, StringPool* sp)
: FileName(filename)
{
stringpool = sp ? sp : new StringPool;
}
FResourceFile::FResourceFile(const char *filename, FileReader &r)
: FResourceFile(filename)
FResourceFile::FResourceFile(const char *filename, FileReader &r, StringPool* sp)
: FResourceFile(filename,sp)
{
Reader = std::move(r);
}
FResourceFile::~FResourceFile()
{
if (!stringpool->shared) delete stringpool;
}
int lumpcmp(const void * a, const void * b)
@ -368,7 +375,7 @@ void FResourceFile::GenerateHash()
for(uint32_t i = 0; i < NumLumps; i++)
{
auto lump = GetLump(i);
md5_append(&state, (const uint8_t*)lump->FullName.c_str(), (unsigned)lump->FullName.length() + 1);
md5_append(&state, (const uint8_t*)lump->FullName, (unsigned)strlen(lump->FullName) + 1);
md5_append(&state, (const uint8_t*)&lump->LumpSize, 4);
}
md5_finish(&state, digest);
@ -453,8 +460,8 @@ int FResourceFile::FilterLumps(const std::string& filtername, void *lumps, size_
for (uint32_t i = start; i < end; ++i, lump_p = (uint8_t *)lump_p + lumpsize)
{
FResourceLump *lump = (FResourceLump *)lump_p;
assert(strnicmp(lump->FullName.c_str(), filter.c_str(), filter.length()) == 0);
lump->LumpNameSetup(lump->FullName.c_str() + filter.length());
assert(strnicmp(lump->FullName, filter.c_str(), filter.length()) == 0);
lump->LumpNameSetup(lump->FullName + filter.length(), nullptr);
}
// Move filtered lumps to the end of the lump list.
@ -523,7 +530,7 @@ void FResourceFile::JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t m
for (void *p = (uint8_t *)lumps + start * lumpsize; p < stop; p = (uint8_t *)p + lumpsize)
{
FResourceLump *lump = (FResourceLump *)p;
lump->FullName = "";
lump->clearName();
}
}
}
@ -556,7 +563,7 @@ bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lump
{
mid = min + (max - min) / 2;
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter));
cmp = strnicmp(lump->FullName, filter, (int)strlen(filter));
if (cmp == 0)
break;
else if (cmp < 0)
@ -576,7 +583,7 @@ bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lump
{
mid = min + (max - min) / 2;
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter));
cmp = strnicmp(lump->FullName, filter, (int)strlen(filter));
// Go left on matches and right on misses.
if (cmp == 0)
max = mid - 1;
@ -591,7 +598,7 @@ bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lump
{
mid = min + (max - min) / 2;
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter));
cmp = strnicmp(lump->FullName, filter, (int)strlen(filter));
// Go right on matches and left on misses.
if (cmp == 0)
min = mid + 1;
@ -613,7 +620,7 @@ FResourceLump *FResourceFile::FindLump(const char *name)
for (unsigned i = 0; i < NumLumps; i++)
{
FResourceLump *lump = GetLump(i);
if (!stricmp(name, lump->FullName.c_str()))
if (!stricmp(name, lump->FullName))
{
return lump;
}
@ -670,12 +677,12 @@ int FUncompressedLump::FillCache()
//
//==========================================================================
FUncompressedFile::FUncompressedFile(const char *filename)
: FResourceFile(filename)
FUncompressedFile::FUncompressedFile(const char *filename, StringPool* sp)
: FResourceFile(filename, sp)
{}
FUncompressedFile::FUncompressedFile(const char *filename, FileReader &r)
: FResourceFile(filename, r)
FUncompressedFile::FUncompressedFile(const char *filename, FileReader &r, StringPool* sp)
: FResourceFile(filename, r, sp)
{}

View File

@ -114,7 +114,7 @@ struct FResourceLump
int LumpSize;
int RefCount;
protected:
std::string FullName;
const char* FullName;
public:
uint8_t Flags;
char * Cache;
@ -126,6 +126,7 @@ public:
Owner = NULL;
Flags = 0;
RefCount = 0;
FullName = "";
}
virtual ~FResourceLump();
@ -134,7 +135,7 @@ public:
virtual int GetFileOffset() { return -1; }
virtual int GetIndexNum() const { return -1; }
virtual int GetNamespace() const { return 0; }
void LumpNameSetup(const char* iname);
void LumpNameSetup(const char* iname, StringPool* allocator);
void CheckEmbedded(LumpFilterInfo* lfi);
virtual FCompressedBuffer GetRawData();
@ -143,7 +144,8 @@ public:
unsigned Size() const{ return LumpSize; }
int LockCount() const { return RefCount; }
const char* getName() { return FullName.c_str(); }
const char* getName() { return FullName; }
void clearName() { FullName = ""; }
protected:
virtual int FillCache() { return -1; }
@ -158,9 +160,10 @@ public:
protected:
uint32_t NumLumps;
char Hash[48];
StringPool* stringpool;
FResourceFile(const char *filename);
FResourceFile(const char *filename, FileReader &r);
FResourceFile(const char *filename, StringPool* sp);
FResourceFile(const char *filename, FileReader &r, StringPool* sp);
// for archives that can contain directories
void GenerateHash();
@ -173,12 +176,12 @@ private:
int FilterLumpsByGameType(LumpFilterInfo *filter, void *lumps, size_t lumpsize, uint32_t max);
bool FindPrefixRange(const char* filter, void *lumps, size_t lumpsize, uint32_t max, uint32_t &start, uint32_t &end);
void JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t max);
static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp);
public:
static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr);
static FResourceFile *OpenResourceFile(const char *filename, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr);
static FResourceFile *OpenDirectory(const char *filename, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr);
static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, StringPool* sp = nullptr);
static FResourceFile *OpenResourceFile(const char *filename, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, StringPool* sp = nullptr);
static FResourceFile *OpenDirectory(const char *filename, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, StringPool* sp = nullptr);
virtual ~FResourceFile();
// If this FResourceFile represents a directory, the Reader object is not usable so don't return it.
FileReader *GetReader() { return Reader.isOpen()? &Reader : nullptr; }
@ -209,8 +212,8 @@ class FUncompressedFile : public FResourceFile
protected:
TArray<FUncompressedLump> Lumps;
FUncompressedFile(const char *filename);
FUncompressedFile(const char *filename, FileReader &r);
FUncompressedFile(const char *filename, StringPool* sp);
FUncompressedFile(const char *filename, FileReader &r, StringPool* sp);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
};