From 6d2047eef6e031587c5f8418bb127d494d8779de Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 01:08:14 +0200 Subject: [PATCH] - also use the stringpool for the lump names in the filesystem. --- src/common/filesystem/filesystem.cpp | 106 ++++++++++++++------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 0574937196..6a0049fc83 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -89,13 +89,13 @@ struct FileSystem::LumpRecord { FResourceLump *lump; LumpShortName shortName; - std::string longName; + const char* LongName; int rfnum; int Namespace; int resourceId; int flags; - void SetFromLump(int filenum, FResourceLump* lmp) + void SetFromLump(int filenum, FResourceLump* lmp, StringPool* sp) { lump = lmp; rfnum = filenum; @@ -105,47 +105,48 @@ struct FileSystem::LumpRecord { UpperCopy(shortName.String, lump->getName()); shortName.String[8] = 0; - longName = ""; + LongName = ""; Namespace = lump->GetNamespace(); resourceId = -1; } else if ((lump->Flags & LUMPF_EMBEDDED) || !lump->getName() || !*lump->getName()) { shortName.qword = 0; - longName = ""; + LongName = ""; Namespace = ns_hidden; resourceId = -1; } else { - longName = lump->getName(); + LongName = lump->getName(); resourceId = lump->GetIndexNum(); // Map some directories to WAD namespaces. // Note that some of these namespaces don't exist in WADS. // CheckNumForName will handle any request for these namespaces accordingly. - Namespace = !strncmp(longName.c_str(), "flats/", 6) ? ns_flats : - !strncmp(longName.c_str(), "textures/", 9) ? ns_newtextures : - !strncmp(longName.c_str(), "hires/", 6) ? ns_hires : - !strncmp(longName.c_str(), "sprites/", 8) ? ns_sprites : - !strncmp(longName.c_str(), "voxels/", 7) ? ns_voxels : - !strncmp(longName.c_str(), "colormaps/", 10) ? ns_colormaps : - !strncmp(longName.c_str(), "acs/", 4) ? ns_acslibrary : - !strncmp(longName.c_str(), "voices/", 7) ? ns_strifevoices : - !strncmp(longName.c_str(), "patches/", 8) ? ns_patches : - !strncmp(longName.c_str(), "graphics/", 9) ? ns_graphics : - !strncmp(longName.c_str(), "sounds/", 7) ? ns_sounds : - !strncmp(longName.c_str(), "music/", 6) ? ns_music : - !strchr(longName.c_str(), '/') ? ns_global : + Namespace = !strncmp(LongName, "flats/", 6) ? ns_flats : + !strncmp(LongName, "textures/", 9) ? ns_newtextures : + !strncmp(LongName, "hires/", 6) ? ns_hires : + !strncmp(LongName, "sprites/", 8) ? ns_sprites : + !strncmp(LongName, "voxels/", 7) ? ns_voxels : + !strncmp(LongName, "colormaps/", 10) ? ns_colormaps : + !strncmp(LongName, "acs/", 4) ? ns_acslibrary : + !strncmp(LongName, "voices/", 7) ? ns_strifevoices : + !strncmp(LongName, "patches/", 8) ? ns_patches : + !strncmp(LongName, "graphics/", 9) ? ns_graphics : + !strncmp(LongName, "sounds/", 7) ? ns_sounds : + !strncmp(LongName, "music/", 6) ? ns_music : + !strchr(LongName, '/') ? ns_global : ns_hidden; if (Namespace == ns_hidden) shortName.qword = 0; - else + else if (strstr(LongName, ".{")) { + std::string longName = LongName; ptrdiff_t encodedResID = longName.find_last_of(".{"); if (resourceId == -1 && encodedResID != std::string::npos) { - const char* p = longName.c_str() + encodedResID; + const char* p = LongName + encodedResID; char* q; int id = (int)strtoull(p+2, &q, 10); // only decimal numbers allowed here. if (q[0] == '}' && (q[1] == '.' || q[1] == 0)) @@ -153,9 +154,10 @@ struct FileSystem::LumpRecord longName.erase(longName.begin() + encodedResID, longName.begin() + (q - p) + 1); resourceId = id; } + LongName = sp->Strdup(longName.c_str()); } ptrdiff_t slash = longName.find_last_of('/'); - std::string base = (slash != std::string::npos) ? longName.c_str() + (slash + 1) : longName.c_str(); + std::string base = (slash != std::string::npos) ? LongName + (slash + 1) : LongName; auto dot = base.find_last_of('.'); if (dot != std::string::npos) base.resize(dot); UpperCopy(shortName.String, base.c_str()); @@ -293,7 +295,7 @@ bool FileSystem::InitMultipleFiles (std::vector& filenames, LumpFil void FileSystem::AddLump(FResourceLump *lump) { FileInfo.resize(FileInfo.size() + 1); - FileInfo.back().SetFromLump(-1, lump); + FileInfo.back().SetFromLump(-1, lump, stringpool); } //----------------------------------------------------------------------- @@ -398,7 +400,7 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf FResourceLump *lump = resfile->GetLump(i); FileInfo.resize(FileInfo.size() + 1); FileSystem::LumpRecord* lump_p = &FileInfo.back(); - lump_p->SetFromLump((int)Files.size(), lump); + lump_p->SetFromLump((int)Files.size(), lump, stringpool); } Files.push_back(resfile); @@ -631,12 +633,12 @@ int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int names for (i = fli[MakeHash(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { - if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; - if (FileInfo[i].longName[len] == 0) break; // this is a full match - if (ignoreext && FileInfo[i].longName[len] == '.') + if (strnicmp(name, FileInfo[i].LongName, len)) continue; + if (FileInfo[i].LongName[len] == 0) break; // this is a full match + if (ignoreext && FileInfo[i].LongName[len] == '.') { // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? - if (strpbrk(FileInfo[i].longName.c_str() + len + 1, "./") == nullptr) break; + if (strpbrk(FileInfo[i].LongName + len + 1, "./") == nullptr) break; } } @@ -661,7 +663,7 @@ int FileSystem::CheckNumForFullName (const char *name, int rfnum) i = FirstLumpIndex_FullName[MakeHash (name) % NumEntries]; while (i != NULL_INDEX && - (stricmp(name, FileInfo[i].longName.c_str()) || FileInfo[i].rfnum != rfnum)) + (stricmp(name, FileInfo[i].LongName) || FileInfo[i].rfnum != rfnum)) { i = NextLumpIndex_FullName[i]; } @@ -712,10 +714,10 @@ int FileSystem::FindFileWithExtensions(const char* name, const char *const *exts for (i = fli[MakeHash(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { - if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; - if (FileInfo[i].longName[len] != '.') continue; // we are looking for extensions but this file doesn't have one. + if (strnicmp(name, FileInfo[i].LongName, len)) continue; + if (FileInfo[i].LongName[len] != '.') continue; // we are looking for extensions but this file doesn't have one. - auto cp = FileInfo[i].longName.c_str() + len + 1; + auto cp = FileInfo[i].LongName + len + 1; // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? if (strpbrk(cp, "./") != nullptr) continue; // No, so it cannot be a valid entry. @@ -751,7 +753,7 @@ int FileSystem::FindResource (int resid, const char *type, int filenum) const no { if (filenum > 0 && FileInfo[i].rfnum != filenum) continue; if (FileInfo[i].resourceId != resid) continue; - auto extp = strrchr(FileInfo[i].longName.c_str(), '.'); + auto extp = strrchr(FileInfo[i].LongName, '.'); if (!extp) continue; if (!stricmp(extp + 1, type)) return i; } @@ -865,13 +867,13 @@ void FileSystem::InitHashChains (void) FirstLumpIndex[j] = i; // Do the same for the full paths - if (!FileInfo[i].longName.empty()) + if (FileInfo[i].LongName[0] != 0) { - j = MakeHash(FileInfo[i].longName.c_str()) % NumEntries; + j = MakeHash(FileInfo[i].LongName) % NumEntries; NextLumpIndex_FullName[i] = FirstLumpIndex_FullName[j]; FirstLumpIndex_FullName[j] = i; - auto nameNoExt = FileInfo[i].longName; + std::string nameNoExt = FileInfo[i].LongName; auto dot = nameNoExt.find_last_of('.'); auto slash = nameNoExt.find_last_of('/'); if ((dot > slash || slash == std::string::npos) && dot != std::string::npos) nameNoExt.resize(dot); @@ -906,7 +908,7 @@ LumpShortName& FileSystem::GetShortName(int i) void FileSystem::RenameFile(int num, const char* newfn) { if ((unsigned)num >= NumEntries) throw FileSystemException("RenameFile: Invalid index"); - FileInfo[num].longName = newfn; + FileInfo[num].LongName = stringpool->Strdup(newfn); // This does not alter the short name - call GetShortname to do that! } @@ -940,13 +942,13 @@ void FileSystem::MoveLumpsInFolder(const char *path) { auto& li = FileInfo[i]; if (li.rfnum >= GetIwadNum()) break; - if (strnicmp(li.longName.c_str(), path, len) == 0) + if (strnicmp(li.LongName, path, len) == 0) { 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, stringpool); // may be able to avoid the string allocation! - ln.SetFromLump(rfnum, ln.lump); + ln.lump->LumpNameSetup(ln.LongName + len, stringpool); // may be able to avoid the string allocation! + ln.SetFromLump(rfnum, ln.lump, stringpool); } } } @@ -1045,7 +1047,7 @@ int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) { while (lump_p <= &FileInfo.back()) { - if (!stricmp(name, lump_p->longName.c_str())) + if (!stricmp(name, lump_p->LongName)) { int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; @@ -1059,10 +1061,10 @@ int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) auto len = strlen(name); while (lump_p <= &FileInfo.back()) { - auto res = strnicmp(name, lump_p->longName.c_str(), len); + auto res = strnicmp(name, lump_p->LongName, len); if (res == 0) { - auto p = lump_p->longName.c_str() + len; + auto p = lump_p->LongName + len; if (*p == 0 || (*p == '.' && strpbrk(p + 1, "./") == 0)) { int lump = int(lump_p - FileInfo.data()); @@ -1119,8 +1121,8 @@ const char *FileSystem::GetFileFullName (int lump, bool returnshort) const { if ((size_t)lump >= NumEntries) return NULL; - else if (!FileInfo[lump].longName.empty()) - return FileInfo[lump].longName.c_str(); + else if (FileInfo[lump].LongName[0] != 0) + return FileInfo[lump].LongName; else if (returnshort) return FileInfo[lump].shortName.String; else return nullptr; @@ -1198,7 +1200,7 @@ const char *FileSystem::GetResourceType(int lump) const return nullptr; else { - auto p = strrchr(FileInfo[lump].longName.c_str(), '.'); + auto p = strrchr(FileInfo[lump].LongName, '.'); if (!p) return ""; // has no extension if (strchr(p, '/')) return ""; // the '.' is part of a directory. return p + 1; @@ -1250,12 +1252,12 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, std::vector