diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/file_7z.cpp index 405e9b919..9b1535be2 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/file_7z.cpp @@ -36,9 +36,7 @@ // Note that 7z made the unwise decision to include windows.h :( #include "7z.h" #include "7zCrc.h" - #include "resourcefile.h" -#include "cmdlib.h" @@ -228,7 +226,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) Archive = NULL; if (res == SZ_ERROR_UNSUPPORTED) { - Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName.c_str()); } else if (res == SZ_ERROR_MEM) { @@ -251,8 +249,8 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) Lumps = new F7ZLump[NumLumps]; F7ZLump *lump_p = Lumps; - TArray nameUTF16; - TArray nameASCII; + std::u16string nameUTF16; + std::string nameASCII; for (uint32_t i = 0; i < NumLumps; ++i) { @@ -271,19 +269,17 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) continue; } - nameUTF16.Resize((unsigned)nameLength); - nameASCII.Resize((unsigned)nameLength); - SzArEx_GetFileNameUtf16(archPtr, i, &nameUTF16[0]); + nameUTF16.resize((unsigned)nameLength); + nameASCII.resize((unsigned)nameLength); + // note that the file system is not equipped to handle non-ASCII, so don't bother with proper Unicode conversion here. + SzArEx_GetFileNameUtf16(archPtr, i, (UInt16*)nameUTF16.data()); for (size_t c = 0; c < nameLength; ++c) { - nameASCII[c] = static_cast(nameUTF16[c]); + nameASCII[c] = tolower(static_cast(nameUTF16[c])); + if (nameASCII[c] == '\\') nameASCII[c] = '/'; } - FixPathSeperator(&nameASCII[0]); - FString name = &nameASCII[0]; - name.ToLower(); - - lump_p->LumpNameSetup(name); + lump_p->LumpNameSetup(nameASCII.c_str()); lump_p->LumpSize = static_cast(SzArEx_GetFileSize(archPtr, i)); lump_p->Owner = this; lump_p->Flags = LUMPF_FULLPATH|LUMPF_COMPRESSED; @@ -303,7 +299,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0])) { - Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName.c_str()); return false; } } diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index 00b1e7a12..688a45aa0 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -84,7 +84,7 @@ public: //========================================================================== FDirectory::FDirectory(const char * directory, bool nosubdirflag) -: FResourceFile(NULL), nosubdir(nosubdirflag) + : FResourceFile(""), nosubdir(nosubdirflag) { FString dirname; @@ -194,7 +194,7 @@ int FDirectory::AddDirectory(const char *dirpath, FileSystemMessageFunc Printf) bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - NumLumps = AddDirectory(FileName, Printf); + NumLumps = AddDirectory(FileName.c_str(), Printf); PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump), filter); return true; } @@ -213,11 +213,11 @@ void FDirectory::AddEntry(const char *fullpath, int size) lump_p->mFullPath = fullpath; // [mxd] Convert name to lowercase - FString name = fullpath + strlen(FileName); - name.ToLower(); + std::string name = fullpath + FileName.length(); + for (auto& c : name) c = tolower(c); // The lump's name is only the part relative to the main directory - lump_p->LumpNameSetup(name); + lump_p->LumpNameSetup(name.c_str()); lump_p->LumpSize = size; lump_p->Owner = this; lump_p->Flags = 0; diff --git a/src/common/filesystem/file_lump.cpp b/src/common/filesystem/file_lump.cpp index 0101aecf4..f16fefaab 100644 --- a/src/common/filesystem/file_lump.cpp +++ b/src/common/filesystem/file_lump.cpp @@ -68,10 +68,8 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file) bool FLumpFile::Open(LumpFilterInfo*) { - FString name(ExtractFileBase(FileName, true)); - Lumps.Resize(1); - Lumps[0].LumpNameSetup(name); + Lumps[0].LumpNameSetup(ExtractBaseName(FileName.c_str(), true).c_str()); Lumps[0].Owner = this; Lumps[0].Position = 0; Lumps[0].LumpSize = (int)Reader.GetLength(); diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index e856212ba..1a256db65 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -181,7 +181,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) // Check again to detect broken wads if (InfoTableOfs + NumLumps*sizeof(wadlump_t) > (unsigned)wadSize) { - Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName.c_str()); return false; } } @@ -201,10 +201,10 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) // This requires explicit toggling for precisely the files that need it. #if 0 Lumps[i].Compressed = !(gameinfo.flags & GI_SHAREWARE) && (n[0] & 0x80) == 0x80; + n[0] &= ~0x80; #else Lumps[i].Compressed = false; #endif - n[0] &= ~0x80; Lumps[i].LumpNameSetup(n); Lumps[i].Owner = this; @@ -218,7 +218,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.GetChars(), Lumps[i].getName()); + 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].LumpSize = Lumps[i].Position = 0; @@ -303,7 +303,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { if (numendmarkers == 0) return; // no markers found - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), endmarker, startmarker); if (flathack) @@ -317,7 +317,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { // We can't add this to the flats namespace but // it needs to be flagged for the texture manager. - Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName.GetChars(), Lumps[ii].getName()); + Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName.c_str(), Lumps[ii].getName()); Lumps[ii].Flags |= LUMPF_MAYBEFLAT; } } @@ -331,7 +331,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name int start, end; if (markers[i].markertype != 0) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), endmarker, startmarker); i++; continue; } @@ -340,21 +340,21 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // skip over subsequent x_START markers while (i < markers.Size() && markers[i].markertype == 0) { - Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.GetChars(), startmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.c_str(), startmarker); i++; continue; } // same for x_END markers while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1)) { - Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.GetChars(), endmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.c_str(), endmarker); i++; continue; } // We found a starting marker but no end marker. Ignore this block. if (i >= markers.Size()) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), startmarker, endmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), startmarker, endmarker); end = NumLumps; } else @@ -363,14 +363,14 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name } // we found a marked block - Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName.GetChars(), startmarker, markers[start].index, end); + Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName.c_str(), startmarker, markers[start].index, end); for(int j = markers[start].index + 1; j < end; j++) { if (Lumps[j].Namespace != ns_global) { if (!warned) { - Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName.GetChars(), j); + Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName.c_str(), j); } warned = true; } @@ -380,7 +380,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // ignore sprite lumps smaller than 8 bytes (the smallest possible) // in size -- this was used by some dmadds wads // as an 'empty' graphics resource - Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName.GetChars(), Lumps[j].getName(), j); + Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName.c_str(), Lumps[j].getName(), j); } else { @@ -450,7 +450,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf) } if (skinned && hasmap) { - Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName.GetChars()); + Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName.c_str()); Printf(FSMessageLevel::Attention, "You should remove the skin from the wad to play these maps.\n"); } } diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 355fefa97..55e4081fe 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -179,7 +179,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (centraldir == 0) { - Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName.c_str()); return false; } @@ -195,7 +195,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.c_str()); return false; } @@ -214,7 +214,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.c_str()); return false; } @@ -253,7 +253,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.c_str()); return false; } @@ -267,7 +267,8 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (!foundprefix) { // check for special names, if one of these gets found this must be treated as a normal zip. - bool isspecial = name.IndexOf("/") < 0 || (filter && filter->reservedFolders.Find(name) < filter->reservedFolders.Size()); + bool isspecial = name.IndexOf("/") < 0 || + (filter && std::find(filter->reservedFolders.begin(), filter->reservedFolders.end(), name.GetChars()) != filter->reservedFolders.end()); if (isspecial) break; name0 = name.Left(name.LastIndexOf("/")+1); name1 = name.Left(name.IndexOf("/") + 1); @@ -292,7 +293,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) // at least one of the more common definition lumps must be present. for (auto &p : filter->requiredPrefixes) { - if (name.IndexOf(name0 + p) == 0 || name.LastIndexOf(p) == ptrdiff_t(name.Len() - strlen(p))) + if (name.IndexOf(name0 + p.c_str()) == 0 || name.LastIndexOf(p.c_str()) == ptrdiff_t(name.Len() - p.length())) { foundspeciallump = true; break; @@ -319,7 +320,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.c_str()); return false; } @@ -346,7 +347,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Method != METHOD_IMPLODE && zip_fh->Method != METHOD_SHRINK) { - Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.GetChars(), name.GetChars(), zip_fh->Method); + Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.c_str(), name.GetChars(), zip_fh->Method); skipped++; continue; } @@ -354,7 +355,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Flags = LittleShort(zip_fh->Flags); if (zip_fh->Flags & ZF_ENCRYPTED) { - Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.GetChars(), name.GetChars()); + Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.c_str(), name.GetChars()); skipped++; continue; } @@ -381,7 +382,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (zip_64->CompressedSize > 0x7fffffff || zip_64->UncompressedSize > 0x7fffffff) { // The file system is limited to 32 bit file sizes; - Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.GetChars(), name.GetChars()); + Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.c_str(), name.GetChars()); skipped++; continue; } diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 2b300abcf..7e6964632 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -233,7 +233,7 @@ bool FileSystem::InitMultipleFiles (TArray &filenames, LumpFilterInfo* AddFile (filenames[i], nullptr, filter, Printf, hashfile); if (i == (unsigned)MaxIwadIndex) MoveLumpsInFolder("after_iwad/"); - FStringf path("filter/%s", Files.Last()->GetHash().GetChars()); + FStringf path("filter/%s", Files.Last()->GetHash()); MoveLumpsInFolder(path); } @@ -1449,9 +1449,9 @@ const char *FileSystem::GetResourceFileName (int rfnum) const noexcept return NULL; } - name = Files[rfnum]->FileName; + name = Files[rfnum]->FileName.c_str(); slash = strrchr (name, '/'); - return (slash != NULL && slash[1] != 0) ? slash+1 : name; + return (slash != nullptr && slash[1] != 0) ? slash+1 : name; } //========================================================================== @@ -1515,7 +1515,7 @@ const char *FileSystem::GetResourceFileFullName (int rfnum) const noexcept return nullptr; } - return Files[rfnum]->FileName; + return Files[rfnum]->FileName.c_str(); } diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index 3ccf506d9..5b0dfdc3c 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -40,6 +40,42 @@ #include "md5.h" +std::string ExtractBaseName(const char* path, bool include_extension) +{ + const char* src, * dot; + + src = path + strlen(path) - 1; + + if (src >= path) + { + // back up until a / or the start + while (src != path && src[-1] != '/' && src[-1] != '\\') // check both on all systems for consistent behavior with archives. + src--; + + if (!include_extension && (dot = strrchr(src, '.'))) + { + return std::string(src, dot - src); + } + else + { + return std::string(src); + } + } + return std::string(); +} + +void strReplace(std::string& str, const char *from, const char* to) +{ + if (*from == 0) + return; + size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::string::npos) + { + str.replace(start_pos, strlen(from), to); + start_pos += strlen(to); + } +} + //========================================================================== // // File reader that reads from a lump's cache @@ -88,10 +124,10 @@ FResourceLump::~FResourceLump() // //========================================================================== -void FResourceLump::LumpNameSetup(FString iname) +void FResourceLump::LumpNameSetup(const char *iname) { // this causes interference with real Dehacked lumps. - if (!iname.CompareNoCase("dehacked.exe")) + if (!stricmp(iname, "dehacked.exe")) { iname = ""; } @@ -115,24 +151,24 @@ static bool IsWadInFolder(const FResourceFile* const archive, const char* const return false; } - const FString dirName = ExtractFileBase(archive->FileName); - const FString fileName = ExtractFileBase(resPath, true); - const FString filePath = dirName + '/' + fileName; + const auto dirName = ExtractBaseName(archive->FileName.c_str()); + const auto fileName = ExtractBaseName(resPath, true); + const std::string filePath = dirName + '/' + fileName; - return 0 == filePath.CompareNoCase(resPath); + return 0 == stricmp(filePath.c_str(), resPath); } void FResourceLump::CheckEmbedded(LumpFilterInfo* lfi) { // Checks for embedded archives - const char *c = strstr(FullName, ".wad"); - if (c && strlen(c) == 4 && (!strchr(FullName, '/') || IsWadInFolder(Owner, FullName))) + const char *c = strstr(FullName.c_str(), ".wad"); + if (c && strlen(c) == 4 && (!strchr(FullName.c_str(), '/') || IsWadInFolder(Owner, FullName.c_str()))) { Flags |= LUMPF_EMBEDDED; } else if (lfi) for (auto& fstr : lfi->embeddings) { - if (!stricmp(FullName, fstr)) + if (!stricmp(FullName.c_str(), fstr.c_str())) { Flags |= LUMPF_EMBEDDED; } @@ -200,7 +236,7 @@ void *FResourceLump::Lock() catch (const FileSystemException& err) { // enrich the message with info about this lump. - throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName.GetChars(), err.what()); + throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName.c_str(), err.what()); } } return Cache; @@ -323,7 +359,7 @@ void FResourceFile::GenerateHash() { // hash the lump directory after sorting - Hash.Format(("%08X-%04X-"), (unsigned)Reader.GetLength(), NumLumps); + auto n = snprintf(Hash, 48, "%08X-%04X-", (unsigned)Reader.GetLength(), NumLumps); MD5Context md5; @@ -331,13 +367,13 @@ void FResourceFile::GenerateHash() for(uint32_t i = 0; i < NumLumps; i++) { auto lump = GetLump(i); - md5.Update((const uint8_t*)lump->FullName.GetChars(), (unsigned)lump->FullName.Len() + 1); + md5.Update((const uint8_t*)lump->FullName.c_str(), (unsigned)lump->FullName.length() + 1); md5.Update((const uint8_t*)&lump->LumpSize, 4); } md5.Final(digest); for (auto c : digest) { - Hash.AppendFormat("%02X", c); + n += snprintf(Hash + n, 3, "%02X", c); } } @@ -366,11 +402,11 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterI ptrdiff_t len; ptrdiff_t lastpos = -1; - FString file; - FString LumpFilter = filter->dotFilter; - while ((len = LumpFilter.IndexOf('.', lastpos+1)) > 0) + std::string file; + std::string& LumpFilter = filter->dotFilter; + while ((len = LumpFilter.find_first_of('.', lastpos+1)) != LumpFilter.npos) { - max -= FilterLumps(LumpFilter.Left(len), lumps, lumpsize, max); + max -= FilterLumps(std::string(LumpFilter, 0, len), lumps, lumpsize, max); lastpos = len; } max -= FilterLumps(LumpFilter, lumps, lumpsize, max); @@ -388,24 +424,23 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterI // //========================================================================== -int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize, uint32_t max) +int FResourceFile::FilterLumps(const std::string& filtername, void *lumps, size_t lumpsize, uint32_t max) { - FString filter; uint32_t start, end; - if (filtername.IsEmpty()) + if (filtername.empty()) { return 0; } - filter << "filter/" << filtername << '/'; + std::string filter = "filter/" + filtername + '/'; - bool found = FindPrefixRange(filter, lumps, lumpsize, max, start, end); + bool found = FindPrefixRange(filter.c_str(), lumps, lumpsize, max, start, end); - // Workaround for old Doom filter names. - if (!found && filtername.IndexOf("doom.id.doom") == 0) + // Workaround for old Doom filter names (todo: move out of here.) + if (!found && filtername.find_first_of("doom.id.doom") == 0) { - filter.Substitute("doom.id.doom", "doom.doom"); - found = FindPrefixRange(filter, lumps, lumpsize, max, start, end); + strReplace(filter, "doom.id.doom", "doom.doom"); + found = FindPrefixRange(filter.c_str(), lumps, lumpsize, max, start, end); } if (found) @@ -417,8 +452,8 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize, for (uint32_t i = start; i < end; ++i, lump_p = (uint8_t *)lump_p + lumpsize) { FResourceLump *lump = (FResourceLump *)lump_p; - assert(lump->FullName.CompareNoCase(filter, (int)filter.Len()) == 0); - lump->LumpNameSetup(lump->FullName.Mid(filter.Len())); + assert(strnicmp(lump->FullName.c_str(), filter.c_str(), filter.length()) == 0); + lump->LumpNameSetup(lump->FullName.c_str() + filter.length()); } // Move filtered lumps to the end of the lump list. @@ -502,7 +537,7 @@ void FResourceFile::JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t m // //========================================================================== -bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize, uint32_t maxlump, uint32_t &start, uint32_t &end) +bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lumpsize, uint32_t maxlump, uint32_t &start, uint32_t &end) { uint32_t min, max, mid, inside; FResourceLump *lump; @@ -520,7 +555,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len()); + cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); if (cmp == 0) break; else if (cmp < 0) @@ -540,7 +575,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len()); + cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); // Go left on matches and right on misses. if (cmp == 0) max = mid - 1; @@ -555,7 +590,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len()); + cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); // Go right on matches and left on misses. if (cmp == 0) min = mid + 1; @@ -577,7 +612,7 @@ FResourceLump *FResourceFile::FindLump(const char *name) for (unsigned i = 0; i < NumLumps; i++) { FResourceLump *lump = GetLump(i); - if (!stricmp(name, lump->FullName)) + if (!stricmp(name, lump->FullName.c_str())) { return lump; } @@ -684,7 +719,7 @@ int FExternalLump::FillCache() Cache = new char[LumpSize]; FileReader f; - if (f.OpenFile(Filename)) + if (f.OpenFile(Filename.c_str())) { auto read = f.Read(Cache, LumpSize); if (read != LumpSize) diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index 96e0e6ca6..ff785747b 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -4,20 +4,23 @@ #define __RESFILE_H #include - +#include +#include #include "files.h" -#include "zstring.h" + +std::string ExtractBaseName(const char* path, bool include_extension = false); +void strReplace(std::string& str, const char* from, const char* to); // user context in which the file system gets opened. This also contains a few callbacks to avoid direct dependencies on the engine. struct LumpFilterInfo { - TArray gameTypeFilter; // this can contain multiple entries - FString dotFilter; + std::vector gameTypeFilter; // this can contain multiple entries + std::string dotFilter; // The following are for checking if the root directory of a zip can be removed. - TArray reservedFolders; - TArray requiredPrefixes; - TArray embeddings; + std::vector reservedFolders; + std::vector requiredPrefixes; + std::vector embeddings; std::function postprocessFunc; }; @@ -107,7 +110,7 @@ struct FResourceLump int LumpSize; int RefCount; protected: - FString FullName; + std::string FullName; public: uint8_t Flags; char * Cache; @@ -127,7 +130,7 @@ public: virtual int GetFileOffset() { return -1; } virtual int GetIndexNum() const { return -1; } virtual int GetNamespace() const { return 0; } - void LumpNameSetup(FString iname); + void LumpNameSetup(const char* iname); void CheckEmbedded(LumpFilterInfo* lfi); virtual FCompressedBuffer GetRawData(); @@ -136,7 +139,7 @@ public: unsigned Size() const{ return LumpSize; } int LockCount() const { return RefCount; } - const char* getName() { return FullName.GetChars(); } + const char* getName() { return FullName.c_str(); } protected: virtual int FillCache() { return -1; } @@ -147,10 +150,10 @@ class FResourceFile { public: FileReader Reader; - FString FileName; + std::string FileName; protected: uint32_t NumLumps; - FString Hash; + char Hash[48]; FResourceFile(const char *filename); FResourceFile(const char *filename, FileReader &r); @@ -159,12 +162,23 @@ protected: void GenerateHash(); void PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterInfo *filter); + void FixPathSeparator(char* path) + { + while (*path) + { + if (*path == '\\') + *path = '/'; + path++; + } + } + + private: uint32_t FirstLump; - int FilterLumps(FString filtername, void *lumps, size_t lumpsize, uint32_t max); + int FilterLumps(const std::string& filtername, void *lumps, size_t lumpsize, uint32_t max); int FilterLumpsByGameType(LumpFilterInfo *filter, void *lumps, size_t lumpsize, uint32_t max); - bool FindPrefixRange(FString filter, void *lumps, size_t lumpsize, uint32_t max, uint32_t &start, uint32_t &end); + 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); @@ -178,7 +192,7 @@ public: uint32_t LumpCount() const { return NumLumps; } uint32_t GetFirstEntry() const { return FirstLump; } void SetFirstLump(uint32_t f) { FirstLump = f; } - const FString &GetHash() const { return Hash; } + const char* GetHash() const { return Hash; } virtual FResourceLump *GetLump(int no) = 0; @@ -210,7 +224,7 @@ protected: struct FExternalLump : public FResourceLump { - FString Filename; + std::string Filename; FExternalLump(const char *_filename, int filesize = -1); virtual int FillCache() override; diff --git a/src/d_main.cpp b/src/d_main.cpp index 0603283e0..937f04bc8 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -202,11 +202,6 @@ extern bool insave; extern TDeletingArray LightDefaults; extern FName MessageBoxClass; -static const char* iwad_folders[] = { "flats/", "textures/", "hires/", "sprites/", "voxels/", "colormaps/", "acs/", "maps/", "voices/", "patches/", "graphics/", "sounds/", "music/", - "materials/", "models/", "fonts/", "brightmaps/"}; -static const char* iwad_reserved[] = { "mapinfo", "zmapinfo", "umapinfo", "gameinfo", "sndinfo", "sndseq", "sbarinfo", "menudef", "gldefs", "animdefs", "decorate", "zscript", "iwadinfo", "maps/" }; - - CUSTOM_CVAR(Float, i_timescale, 1.0f, CVAR_NOINITCALL | CVAR_VIRTUAL) { if (netgame) @@ -1920,8 +1915,9 @@ static FString ParseGameInfo(TArray &pwads, const char *fn, const char void GetReserved(LumpFilterInfo& lfi) { - for (auto p : iwad_folders) lfi.reservedFolders.Push(p); - for (auto p : iwad_reserved) lfi.requiredPrefixes.Push(p); + lfi.reservedFolders = { "flats/", "textures/", "hires/", "sprites/", "voxels/", "colormaps/", "acs/", "maps/", "voices/", "patches/", "graphics/", "sounds/", "music/", + "materials/", "models/", "fonts/", "brightmaps/" }; + lfi.requiredPrefixes = { "mapinfo", "zmapinfo", "umapinfo", "gameinfo", "sndinfo", "sndseq", "sbarinfo", "menudef", "gldefs", "animdefs", "decorate", "zscript", "iwadinfo", "maps/" }; } static FString CheckGameInfo(TArray & pwads) @@ -3065,7 +3061,7 @@ static int FileSystemPrintf(FSMessageLevel level, const char* fmt, ...) DPrintf(DMSG_NOTIFY, "%s", text.GetChars()); break; } - return text.Len(); + return (int)text.Len(); } //========================================================================== // @@ -3138,9 +3134,9 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray& allwads, TArr for (auto& inf : blanket) { - if (gameinfo.gametype & inf.match) lfi.gameTypeFilter.Push(inf.name); + if (gameinfo.gametype & inf.match) lfi.gameTypeFilter.push_back(inf.name); } - lfi.gameTypeFilter.Push(FStringf("game-%s", GameTypeName())); + lfi.gameTypeFilter.push_back(FStringf("game-%s", GameTypeName()).GetChars()); GetReserved(lfi);