From 3d673e3f20eca15de1e4485d8393031ead570db3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 00:56:31 +0200 Subject: [PATCH] - use a string pool to store the filenames in FResourceLump. --- src/common/filesystem/file_7z.cpp | 12 ++-- src/common/filesystem/file_directory.cpp | 12 ++-- src/common/filesystem/file_grp.cpp | 12 ++-- src/common/filesystem/file_lump.cpp | 12 ++-- src/common/filesystem/file_pak.cpp | 12 ++-- src/common/filesystem/file_rff.cpp | 12 ++-- src/common/filesystem/file_ssi.cpp | 14 ++-- src/common/filesystem/file_wad.cpp | 16 ++--- src/common/filesystem/file_whres.cpp | 12 ++-- src/common/filesystem/file_zip.cpp | 10 +-- src/common/filesystem/file_zip.h | 2 +- src/common/filesystem/filesystem.cpp | 12 ++-- src/common/filesystem/filesystem.h | 2 + src/common/filesystem/fs_stringpool.cpp | 2 +- src/common/filesystem/fs_stringpool.h | 6 +- src/common/filesystem/resourcefile.cpp | 83 +++++++++++++----------- src/common/filesystem/resourcefile.h | 25 +++---- 17 files changed, 137 insertions(+), 119 deletions(-) diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/file_7z.cpp index 5539d5448..391a8aab2 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/file_7z.cpp @@ -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(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 diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index 7117df760..a99e6fb56 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -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; diff --git a/src/common/filesystem/file_grp.cpp b/src/common/filesystem/file_grp.cpp index 4765bcde0..dd8099a2a 100644 --- a/src/common/filesystem/file_grp.cpp +++ b/src/common/filesystem/file_grp.cpp @@ -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 diff --git a/src/common/filesystem/file_lump.cpp b/src/common/filesystem/file_lump.cpp index 60c957081..540ee6dd7 100644 --- a/src/common/filesystem/file_lump.cpp +++ b/src/common/filesystem/file_lump.cpp @@ -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; diff --git a/src/common/filesystem/file_pak.cpp b/src/common/filesystem/file_pak.cpp index 4003ce396..dfcc22ef4 100644 --- a/src/common/filesystem/file_pak.cpp +++ b/src/common/filesystem/file_pak.cpp @@ -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 diff --git a/src/common/filesystem/file_rff.cpp b/src/common/filesystem/file_rff.cpp index 723d184e6..5204d7f0f 100644 --- a/src/common/filesystem/file_rff.cpp +++ b/src/common/filesystem/file_rff.cpp @@ -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 diff --git a/src/common/filesystem/file_ssi.cpp b/src/common/filesystem/file_ssi.cpp index 6bf60cc1e..0cfab8729 100644 --- a/src/common/filesystem/file_ssi.cpp +++ b/src/common/filesystem/file_ssi.cpp @@ -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; diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index fb77a8781..badcc271f 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -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 diff --git a/src/common/filesystem/file_whres.cpp b/src/common/filesystem/file_whres.cpp index d7149f116..8629e6a64 100644 --- a/src/common/filesystem/file_whres.cpp +++ b/src/common/filesystem/file_whres.cpp @@ -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; diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 492a24276..175c53e18 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -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 diff --git a/src/common/filesystem/file_zip.h b/src/common/filesystem/file_zip.h index 028731f28..5b49b714f 100644 --- a/src/common/filesystem/file_zip.h +++ b/src/common/filesystem/file_zip.h @@ -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; } diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 097b6ffe5..057493719 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -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); } } diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index 29b9b8b4e..7dcda2f09 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -204,6 +204,8 @@ protected: int IwadIndex = -1; int MaxIwadIndex = -1; + StringPool* stringpool; + private: void DeleteAll(); void MoveLumpsInFolder(const char *); diff --git a/src/common/filesystem/fs_stringpool.cpp b/src/common/filesystem/fs_stringpool.cpp index b828d398f..29a472309 100644 --- a/src/common/filesystem/fs_stringpool.cpp +++ b/src/common/filesystem/fs_stringpool.cpp @@ -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; } diff --git a/src/common/filesystem/fs_stringpool.h b/src/common/filesystem/fs_stringpool.h index ce1e7d83f..331f768f7 100644 --- a/src/common/filesystem/fs_stringpool.h +++ b/src/common/filesystem/fs_stringpool.h @@ -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*); diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index 718069c51..5f044371f 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -37,6 +37,7 @@ #include #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) {} diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index 2345f332f..6acf0b89b 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -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 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; } };