2020-04-11 21:54:33 +00:00
|
|
|
#pragma once
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// DESCRIPTION:
|
|
|
|
// File system I/O functions.
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 18:36:19 +00:00
|
|
|
#include "fs_files.h"
|
2020-04-11 21:54:33 +00:00
|
|
|
#include "resourcefile.h"
|
|
|
|
|
2023-08-23 18:36:19 +00:00
|
|
|
namespace FileSys {
|
|
|
|
|
2020-04-11 21:54:33 +00:00
|
|
|
struct FolderEntry
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
unsigned lumpnum;
|
|
|
|
};
|
|
|
|
|
|
|
|
class FileSystem
|
|
|
|
{
|
|
|
|
public:
|
2023-08-19 14:57:37 +00:00
|
|
|
FileSystem();
|
2024-11-24 16:22:47 +00:00
|
|
|
virtual ~FileSystem ();
|
|
|
|
// do not copy!
|
|
|
|
FileSystem(const FileSystem& other) = delete;
|
|
|
|
FileSystem& operator =(const FileSystem& other) = delete;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
bool Initialize(std::vector<std::string>& filenames, FileSystemFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, bool allowduplicates = false);
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
// The container for the IWAD
|
|
|
|
int GetBaseNum() { return BaseIndex; }
|
|
|
|
void SetBaseNum(int x) { BaseIndex = x; }
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
int GetMaxBaseNum() { return MaxBaseIndex; }
|
|
|
|
void SetMaxBaseNum(int x) { MaxBaseIndex = x; }
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
int CheckIfContainerLoaded (const char *name) noexcept;
|
|
|
|
void AddAdditionalFile(const char* filename, FileReader* wadinfo = NULL) {}
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
const char *GetContainerName (int container) const noexcept;
|
|
|
|
const char *GetContainerFullName (int container) const noexcept;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
int GetFirstEntry(int container) const noexcept;
|
|
|
|
int GetLastEntry(int container) const noexcept;
|
|
|
|
int GetEntryCount(int container) const noexcept;
|
|
|
|
int GetContainerFlags(int container) const noexcept;
|
2023-08-23 18:36:19 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
int FindFile (const char *cname, bool ignoreext = false) const;
|
|
|
|
int GetFileInContainer (const char *name, int wadfile) const;
|
|
|
|
int GetFile (const char *name) const;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2023-08-23 18:36:19 +00:00
|
|
|
bool FileExists(const char* name) const
|
2020-04-11 21:54:33 +00:00
|
|
|
{
|
|
|
|
return FindFile(name) >= 0;
|
|
|
|
}
|
|
|
|
|
2023-08-23 18:36:19 +00:00
|
|
|
bool FileExists(const std::string& name) const
|
2020-04-11 21:54:33 +00:00
|
|
|
{
|
|
|
|
return FindFile(name.c_str()) >= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenameFile(int num, const char* fn);
|
|
|
|
bool CreatePathlessCopy(const char* name, int id, int flags);
|
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
void ReadFile (int filenum, void *dest);
|
2023-08-19 17:32:17 +00:00
|
|
|
// These should only be used if the file data really needs padding.
|
2024-11-24 16:22:47 +00:00
|
|
|
FileData ReadFile (int filenum);
|
|
|
|
FileData ReadFileFullName(const char* name) { return ReadFile(GetFile(name)); }
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
FileReader OpenFileReader(int filenum, int readertype, int readerflags); // opens a reader that redirects to the containing file's one.
|
2020-04-11 21:54:33 +00:00
|
|
|
FileReader OpenFileReader(const char* name);
|
2023-12-17 11:48:03 +00:00
|
|
|
FileReader ReopenFileReader(const char* name, bool alwayscache = false);
|
2024-11-24 16:22:47 +00:00
|
|
|
FileReader OpenFileReader(int filenum)
|
2023-12-17 11:48:03 +00:00
|
|
|
{
|
2024-11-24 16:22:47 +00:00
|
|
|
return OpenFileReader(filenum, READER_SHARED, READERFLAG_SEEKABLE);
|
2023-12-17 11:48:03 +00:00
|
|
|
}
|
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
FileReader ReopenFileReader(int filenum, bool alwayscache = false)
|
2023-12-17 11:48:03 +00:00
|
|
|
{
|
2024-11-24 16:22:47 +00:00
|
|
|
return OpenFileReader(filenum, alwayscache ? READER_CACHED : READER_NEW, READERFLAG_SEEKABLE);
|
2023-12-17 11:48:03 +00:00
|
|
|
}
|
|
|
|
|
2020-04-11 21:54:33 +00:00
|
|
|
|
|
|
|
int FindLumpFullName(const char* name, int* lastlump, bool noext = false);
|
|
|
|
|
2023-08-23 18:36:19 +00:00
|
|
|
int FindFileWithExtensions(const char* name, const char* const* exts, int count) const;
|
2020-04-11 21:54:33 +00:00
|
|
|
int FindResource(int resid, const char* type, int filenum = -1) const noexcept;
|
|
|
|
int GetResource(int resid, const char* type, int filenum = -1) const;
|
|
|
|
|
2023-08-23 18:36:19 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
ptrdiff_t FileLength(int filenum) const;
|
|
|
|
int GetFileFlags (int filenum); // Return the flags for this filenum
|
|
|
|
const char* GetFileName(int filenum) const; // Gets uninterpreted name from the FResourceFile
|
|
|
|
std::string GetFileFullPath (int filenum) const; // [RH] Returns wad's name + filenum's full name
|
|
|
|
int GetFileContainer (int filenum) const;
|
|
|
|
// [RH] Returns container for a specified filenum
|
|
|
|
int GetResourceId(int filenum) const; // Returns the RFF index number for this filenum
|
|
|
|
const char* GetResourceType(int filenum) const;
|
2023-08-20 00:15:57 +00:00
|
|
|
unsigned GetFilesInFolder(const char *path, std::vector<FolderEntry> &result, bool atomic) const;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
int GetFileCount() const
|
2020-04-11 21:54:33 +00:00
|
|
|
{
|
|
|
|
return NumEntries;
|
|
|
|
}
|
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
int GetContainerCount() const
|
2020-04-11 21:54:33 +00:00
|
|
|
{
|
2023-08-20 00:15:57 +00:00
|
|
|
return (int)Files.size();
|
2020-04-11 21:54:33 +00:00
|
|
|
}
|
|
|
|
|
2023-12-10 14:23:21 +00:00
|
|
|
int AddFromBuffer(const char* name, char* data, int size, int id, int flags);
|
2024-11-24 16:22:47 +00:00
|
|
|
FileReader* GetFileReader(int container); // Gets a FileReader object to the entire WAD
|
2020-04-11 21:54:33 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
struct LumpRecord;
|
2024-11-24 16:22:47 +00:00
|
|
|
const uint32_t NULL_INDEX = 0xffffffff;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2023-08-20 00:15:57 +00:00
|
|
|
std::vector<FResourceFile *> Files;
|
|
|
|
std::vector<LumpRecord> FileInfo;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2023-08-20 00:15:57 +00:00
|
|
|
std::vector<uint32_t> Hashes; // one allocation for all hash lists.
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
uint32_t *FirstFileIndex_FullName = nullptr; // The same information for fully qualified paths from .zips
|
|
|
|
uint32_t *NextFileIndex_FullName = nullptr;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
uint32_t *FirstFileIndex_NoExt = nullptr; // The same information for fully qualified paths from .zips
|
|
|
|
uint32_t *NextFileIndex_NoExt = nullptr;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
uint32_t* FirstFileIndex_ResId = nullptr; // The same information for fully qualified paths from .zips
|
|
|
|
uint32_t* NextFileIndex_ResId = nullptr;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
|
|
|
uint32_t NumEntries = 0; // Not necessarily the same as FileInfo.Size()
|
2024-01-06 08:31:07 +00:00
|
|
|
uint32_t NumWads = 0;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
int BaseIndex = -1;
|
|
|
|
int MaxBaseIndex = -1;
|
2020-04-11 21:54:33 +00:00
|
|
|
|
2023-09-23 07:56:27 +00:00
|
|
|
StringPool* stringpool = nullptr;
|
2023-08-23 18:36:19 +00:00
|
|
|
|
2020-04-11 21:54:33 +00:00
|
|
|
private:
|
|
|
|
void DeleteAll();
|
2024-11-24 16:22:47 +00:00
|
|
|
void MoveFilesInFolder(const char *);
|
|
|
|
void AddFile(const char* filename, FileReader* wadinfo, FileSystemFilterInfo* filter, FileSystemMessageFunc Printf);
|
|
|
|
protected:
|
|
|
|
|
|
|
|
// These two functions must be overridden by subclasses which want to extend the file system.
|
|
|
|
virtual bool InitFiles(std::vector<std::string>& filenames, FileSystemFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, bool allowduplicates = false);
|
|
|
|
public:
|
|
|
|
virtual void InitHashChains();
|
2020-04-11 21:54:33 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2024-11-24 16:22:47 +00:00
|
|
|
//djb2 hash algorithm with case insensitivity hack
|
|
|
|
inline static uint32_t MakeHash(const char* str, size_t length = SIZE_MAX)
|
|
|
|
{
|
|
|
|
uint32_t hash = 5381;
|
|
|
|
uint32_t c;
|
|
|
|
while (length-- > 0 && (c = *str++)) hash = hash * 33 + (c | 32);
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-08-23 18:36:19 +00:00
|
|
|
}
|