#pragma once #include #include //used only for appearances atm //TODO: add actual File struct typedef char* File; class Filesystem { public: static bool& IsPacked() { static bool isPacked = true; return isPacked; } static void Init(const char* cwd, std::vector searchPaths) { //TODO: allow explicit disable of physfs if(IsPacked()) { PHYSFS_init(cwd); PHYSFS_permitSymbolicLinks(false); //for security for(auto path : searchPaths) { PHYSFS_addToSearchPath(("game/" + path).c_str(), 1); } PHYSFS_addToSearchPath("game/data.vpf", 1); PHYSFS_addToSearchPath("game/", 1); } } static File GetFileHandle(const std::string& path, int& size, bool forcePacked = false) { if(IsPacked() || forcePacked) { PHYSFS_file* indexFile = PHYSFS_openRead(path.c_str()); if(!indexFile) { size = 0; return nullptr; } char* myBuf; myBuf = new char[PHYSFS_fileLength(indexFile) + 1]; PHYSFS_read(indexFile, myBuf, 1, PHYSFS_fileLength(indexFile)); myBuf[PHYSFS_fileLength(indexFile)] = '\0'; size = PHYSFS_fileLength(indexFile); PHYSFS_close(indexFile); return myBuf; } else { char* buffer; int string_size, read_size; FILE* handler = fopen(path.c_str(), "r"); if(handler) { fseek(handler, 0, SEEK_END); string_size = ftell(handler); rewind(handler); buffer = static_cast(malloc(sizeof(char) * (string_size + 1))); read_size = fread(buffer, sizeof(char), string_size, handler); buffer[string_size] = '\0'; if(string_size != read_size) { free(buffer); size = 0; return nullptr; } size = read_size; fclose(handler); return buffer; } else { size = 0; return nullptr; } } } static void FreeFileHandle(File handle) { //don't delete physfs' file pointers! if(!Filesystem::IsPacked()) delete handle; } //platform-specific file methods static void CreateDirectory(const std::string& path); static void CopyFile(const std::string& src, const std::string& dst, bool overwrite = false); static void CopyDirectory(const std::string& src, const std::string& dst, bool overwrite = false); static void Remove(const std::string& path); static std::string Canonical(const std::string& path); static std::vector DirectoryContents(const std::string& directory); static bool DirectoryExists(const std::string& path); static bool FileExists(const std::string& path); };