etqw-sdk/source/framework/FileSystem.h
2008-05-29 00:00:00 +00:00

422 lines
18 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __FILESYSTEM_H__
#define __FILESYSTEM_H__
#if defined( _DEBUG )
#define SD_LOAD_STATISTICS
#endif
#include "../libs/filelib/File.h"
/*class sdFileIOLog {
public:
void PrintFileHandles();
FILE* fopen( const char* filename, const char* mode );
int fclose( FILE* stream );
private:
struct fileHandle_t {
FILE* stream;
idStr fileName;
};
void AddFileHandle( fileHandle_t& handle );
void RemoveFileHandle( FILE* stream );
private:
idList< fileHandle_t > fileHandles;
};
extern sdFileIOLog* fileIOLog;*/
#if defined ( SVN_LOCK )
struct svnLock_t {
bool created;
char osPath[ MAX_STRING_CHARS ];
};
extern svnLock_t svnLock;
#endif /* SVN_LOCK */
/*
===============================================================================
File System
No stdio calls should be used by any part of the game, because of all sorts
of directory and separator char issues. Throughout the game a forward slash
should be used as a separator. The file system takes care of the conversion
to an OS specific separator. The file system treats all file and directory
names as case insensitive.
The following cvars store paths used by the file system:
"fs_basepath" path to local install, read-only
"fs_savepath" path to extracted dlls, downloaded game data, etc. files read & write
"fs_userpath" path to config, save game, etc. files, read & write
"fs_cdpath" path to cd, read-only
"fs_devpath" path to files created during development, read & write
The base path for file saving can be set to "fs_savepath" or "fs_devpath".
===============================================================================
*/
const unsigned FILE_NOT_FOUND_TIMESTAMP = 0xFFFFFFFF;
const int MAX_PURE_PAKS = 128;
const int MAX_OSPATH = 256;
typedef enum {
PURE_OK, // we are good to connect as-is
PURE_RESTART, // restart required
PURE_MISSING, // pak files missing on the client
PURE_NODLL // no DLL could be extracted
} fsPureReply_t;
typedef enum {
DLTYPE_URL,
DLTYPE_FILE,
} dlType_t;
typedef enum {
DL_WAIT, // waiting in the list for beginning of the download
DL_INPROGRESS, // in progress
DL_DONE, // download completed, success
DL_ABORTING, // this one can be set during a download, it will force the next progress callback to abort - then will go to DL_FAILED
DL_FAILED
} dlStatus_t;
typedef enum {
FILE_EXEC,
FILE_OPEN
} dlMime_t;
typedef enum {
FIND_NO,
FIND_YES,
FIND_ADDON
} findFile_t;
typedef struct urlDownload_s {
idStr url;
idStr urlAuth;
idStr referer;
char dlerror[ MAX_STRING_CHARS ];
int dltotal;
int dlnow;
int curlstatus;
dlStatus_t status;
} urlDownload_t;
typedef struct fileDownload_s {
int offset;
int length;
void * buffer;
} fileDownload_t;
typedef struct proxyDownload_s {
idStr proxyUrl;
idStr proxyAuth;
} proxyDownload_t;
struct backgroundDownload_t {
backgroundDownload_t* next; // set by the fileSystem
dlType_t opcode;
idFile* fh;
fileDownload_t file;
urlDownload_t url;
proxyDownload_t proxy;
volatile bool completed;
};
// file list for directory listings
class idFileList {
friend class idFileSystemLocal;
public:
const char * GetBasePath( void ) const { return basePath; }
int GetNumFiles( void ) const { return list.Num(); }
const char * GetFile( int index ) const { return list[index]; }
const idStrList & GetList( void ) const { return list; }
private:
idStr basePath;
idStrList list;
};
// mod list
class idModList {
friend class idFileSystemLocal;
public:
int GetNumMods( void ) const { return mods.Num(); }
const char * GetMod( int index ) const { return mods[index]; }
const char * GetDescription( int index ) const { return descriptions[index]; }
private:
idStrList mods;
idStrList descriptions;
};
struct metaDataContext_t {
const idDict* meta;
bool addon;
idStr pak;
};
class sdAddonMetaDataList {
friend class idFileSystemLocal;
public:
~sdAddonMetaDataList( void ) {
for( int i = 0; i < meta.Num(); i++ ) {
delete meta[ i ].meta;
}
}
int GetNumMetaData() const { return meta.Num(); }
const idDict& GetMetaData( int index ) const { return *meta[ index ].meta; }
const metaDataContext_t&GetMetaDataContext( int index ) const { return meta[ index ]; }
const idDict* FindMetaData( const char* name, const idDict* defaultDict = NULL ) {
for( int i = 0; i < meta.Num(); i++ ) {
const char* value = meta[ i ].meta->GetString( "metadata_name" );
if( !idStr::Icmp( name, value ) ) {
return meta[ i ].meta;
}
}
return defaultDict;
}
int FindMetaDataIndex( const char* name ) {
for( int i = 0; i < meta.Num(); i++ ) {
const char* value = meta[ i ].meta->GetString( "metadata_name" );
if( !idStr::Icmp( name, value ) ) {
return i;
}
}
return -1;
}
const metaDataContext_t* FindMetaDataContext( const char* name ) const {
for( int i = 0; i < meta.Num(); i++ ) {
const char* value = meta[ i ].meta->GetString( "metadata_name" );
if( !idStr::Icmp( name, value ) ) {
return &meta[ i ];
}
}
return NULL;
}
private:
idList<metaDataContext_t> meta;
};
class idFileSystem {
public:
virtual ~idFileSystem() {}
// Initializes the file system.
virtual void Init( bool quiet = false ) = 0;
// Restarts the file system.
virtual void Restart( void ) = 0;
// Shutdown the file system.
virtual void Shutdown( bool reloading ) = 0;
// Returns true if the file system is initialized.
virtual bool IsInitialized( void ) const = 0;
// Enables/Disables quiet mode.
virtual void SetQuietMode( bool enable ) = 0;
// Returns quiet mode status.
virtual bool GetQuietMode( void ) const = 0;
// Returns true if we are doing an fs_copyfiles.
virtual bool PerformingCopyFiles( void ) const = 0;
// Returns a list of mods found along with descriptions
// 'mods' contains the directory names to be passed to fs_game
// 'descriptions' contains a free form string to be used in the UI
virtual idModList * ListMods( void ) = 0;
// Returns a list of metadata specified in addon.conf (and pakmeta.conf)
virtual sdAddonMetaDataList* ListAddonMetaData( const char* metaDataTag ) = 0;
// Frees the given metadata list
virtual void FreeAddonMetaDataList( sdAddonMetaDataList* list ) = 0;
// Frees the given mod list
virtual void FreeModList( idModList *modList ) = 0;
// Lists dll files with the directories specified by fs_toolsPath
// Directory should not have either a leading or trailing '/'
virtual idFileList * ListTools() = 0;
// Lists files with the given extension in the given directory.
// Directory should not have either a leading or trailing '/'
// The returned files will not include any directories or '/' unless fullRelativePath is set.
// The extension must include a leading dot and may not contain wildcards.
// If extension is "/", only subdirectories will be returned.
virtual idFileList * ListFiles( const char *relativePath, const char *extension, bool sort = false, bool fullRelativePath = false, const char* gamedir = NULL ) = 0;
// Lists files in the given directory and all subdirectories with the given extension.
// Directory should not have either a leading or trailing '/'
// The returned files include a full relative path.
// The extension must include a leading dot and may not contain wildcards.
virtual idFileList * ListFilesTree( const char *relativePath, const char *extension, bool sort = false, const char* gamedir = NULL ) = 0;
// Frees the given file list.
virtual void FreeFileList( idFileList *fileList ) = 0;
// Converts a relative path to a full OS path.
virtual const char * OSPathToRelativePath( const char *OSPath ) = 0;
// Converts a full OS path to a relative path.
virtual const char * RelativePathToOSPath( const char *relativePath, const char *basePath = "fs_devpath" ) = 0;
// Builds a full OS path from the given components.
virtual const char * BuildOSPath( const char *base, const char *game, const char *relativePath ) = 0;
// Returns a full OS path where the initial base of the file system exists
virtual const char * GetBasePath() const = 0;
// Returns a full OS path where files can be written to
virtual const char * GetSavePath() const = 0;
// Returns a full OS path where user visible files can be written to
virtual const char * GetUserPath() const = 0;
// Returns the current game path
virtual const char * GetGamePath() const = 0;
// Creates the given OS path for as far as it doesn't exist already.
virtual void CreateOSPath( const char *OSPath ) = 0;
// Returns true if a file is in a pak file.
virtual bool FileIsInPAK( const char *relativePath ) = 0;
// Returns a space separated string containing the checksums of all referenced pak files.
// will call SetPureServerChecksums internally to restrict itself
virtual void UpdatePureServerChecksums( void ) = 0;
// setup the mapping of OS -> game pak checksum
virtual bool UpdateGamePakChecksums( void ) = 0;
// 0-terminated list of pak checksums
// if pureChecksums[ 0 ] == 0, all data sources will be allowed
// otherwise, only pak files that match one of the checksums will be checked for files
// with the sole exception of .cfg files.
// the function tries to configure pure mode from the paks already referenced and this new list
// it returns wether the switch was successfull, and sets the missing checksums
// the process is verbosive when fs_debug 1
virtual fsPureReply_t SetPureServerChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum, int missingChecksums[ MAX_PURE_PAKS ], int *missingGamePakChecksum, const char *serverVersion = NULL ) = 0;
// fills a 0-terminated list of pak checksums for a client
// if OS is -1, give the current game pak checksum. if >= 0, lookup the game pak table (server only)
virtual void GetPureServerChecksums( int checksums[ MAX_PURE_PAKS ], int OS, int *gamePakChecksum ) = 0;
// before doing a restart, force the pure list and the search order
// if the given checksum list can't be completely processed and set, will error out
virtual void SetRestartChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum ) = 0;
// equivalent to calling SetPureServerChecksums with an empty list
virtual void ClearPureChecksums( void ) = 0;
// get a mask of supported OSes. if not pure, returns -1
virtual unsigned int GetOSMask( void ) = 0;
// returns true if the file exists
virtual bool FileExists( const char *relativePath ) = 0;
// returns true if the file exists
virtual bool FileExistsExplicit( const char *OSPath ) = 0;
// the timestamp or FILE_NOT_FOUND_TIMESTAMP
virtual unsigned int GetTimestamp( const char *relativePath ) = 0;
// Reads a complete file.
// Returns the length of the file, or -1 on failure.
// A null buffer will just return the file length without loading.
// A null timestamp will be ignored.
// As a quick check for existence. -1 length == not present.
// A 0 byte will always be appended at the end, so string ops are safe.
// The buffer should be considered read-only, because it may be cached for other uses.
// when markPaksReferenced is false the file's pk4 (if any) will not be added to the referenced list
// (this is useful for reading metadata for things like the server browser)
virtual int ReadFile( const char *relativePath, void **buffer, unsigned int *timestamp = NULL, bool markPaksReferenced = true ) = 0;
// Frees the memory allocated by ReadFile.
virtual void FreeFile( void *buffer ) = 0;
// Writes a complete file, will create any needed subdirectories.
// Returns the length of the file, or -1 on failure.
virtual int WriteFile( const char *relativePath, const void *buffer, int size, const char *basePath = "fs_savepath" ) = 0;
// Removes the given file.
virtual void RemoveFile( const char *relativePath ) = 0;
// Opens a file for reading.
virtual idFile * OpenFileRead( const char *relativePath, bool allowCopyFiles = true, const char* gamedir = NULL, bool markPaksReferenced = true ) = 0;
// Opens a file for writing, will create any needed subdirectories.
virtual idFile * OpenFileWrite( const char *relativePath, const char *basePath = "fs_savepath" ) = 0;
// Opens a file for writing at the end.
virtual idFile * OpenFileAppend( const char *filename, bool sync = false, const char *basePath = "fs_savepath" ) = 0;
// Opens a file for reading, writing, or appending depending on the value of mode.
virtual idFile * OpenFileByMode( const char *relativePath, fsMode_t mode ) = 0;
// Opens a file for reading from a full OS path.
virtual idFile * OpenExplicitFileRead( const char *OSPath ) = 0;
// Opens a file for writing to a full OS path.
virtual idFile * OpenExplicitFileWrite( const char *OSPath ) = 0;
// Removes the given file from a full OS path
virtual void RemoveExplicitFile( const char* OSPath ) = 0;
// Removes the given directory from a full OS path
virtual bool RemoveExplicitDir( const char* OSPath, bool nonEmpty, bool recursive ) = 0;
// Closes a file.
virtual void CloseFile( idFile *f ) = 0;
// Returns immediately, performing the read from a background thread.
virtual void BackgroundDownload( backgroundDownload_t *bgl ) = 0;
// Cancel the pending background download
virtual bool CancelBackgroundDownload( backgroundDownload_t *bgl ) = 0;
// resets the bytes read counter
virtual void ResetReadCount( void ) = 0;
// retrieves the current read count
virtual int GetReadCount( void ) = 0;
// adds to the read count
virtual void AddToReadCount( int c ) = 0;
// look for a dynamic module
virtual void FindDLL( const char *basename, char dllPath[ MAX_OSPATH ], bool updateChecksum, bool pureCheck ) = 0;
// case sensitive filesystems use an internal directory cache
// the cache is cleared when calling OpenFileWrite and RemoveFile
// in some cases you may need to use this directly
virtual void ClearDirCache( void ) = 0;
virtual idFile_Memory* OpenMemoryFile( const char* name ) = 0;
virtual idFile_Buffered*OpenBufferedFile( idFile* file ) = 0;
// don't use for large copies - allocates a single memory block for the copy
virtual bool CopyFile( const char *fromOSPath, const char *toOSPath ) = 0;
// lookup a relative path, return the size or 0 if not found
virtual int ValidateDownloadPakForChecksum( int checksum, char path[ MAX_STRING_CHARS ], bool isGamePak ) = 0;
// verify the file can be downloaded, lookup an absolute (OS) path, return the size or 0 if not found
virtual int ValidateDownloadPakForRelativePath( const char *relativePath, char path[ MAX_STRING_CHARS ], bool &isGamePakReturn ) = 0;
virtual idFile * MakeTemporaryFile( void ) = 0;
// make downloaded pak files known so pure negotiation works next time
virtual int AddPackFile( const char* path ) = 0;
// look for a file in the loaded paks or the addon paks
// if the file is found in addons, FS's internal structures are ready for a reloadEngine
virtual findFile_t FindFile( const char *path ) = 0;
// ignore case and seperator char distinctions
virtual bool FilenameCompare( const char *s1, const char *s2 ) const = 0;
virtual unsigned long FileChecksum( idFile* o, unsigned char *md5digest = NULL ) = 0;
virtual unsigned long FileChecksum( FILE* o, unsigned char *md5digest = NULL ) = 0;
virtual void BeginLevelLoadStatistics() = 0;
virtual void AddLevelLoadStatistic( const char* extension, int numBytes ) = 0;
virtual void EndLevelLoadStatistics() = 0;
virtual void ReportLevelLoadStatistics() = 0;
// is the pack currently referenced?
virtual bool IsAddonPackReferenced( const char* pak ) = 0;
// ensure that the pack is loaded after the next pure restart
virtual void ReferenceAddonPack( const char* pak ) = 0;
// textures
virtual void ReadTGA( const char *name, byte **pic, int *width, int *height, unsigned *timestamp = 0, bool markPaksReferenced = true ) = 0;
virtual void WriteTGA( const char* name, const byte* pic, int width, int height ) = 0;
virtual void FreeTGA( byte* pic ) = 0;
};
extern idFileSystem * fileSystem;
// Auto-close files on destruction
// Prefer this to using idFile* in most cases, since this is exception-safe
struct sdCleanupPolicy_CloseFile {
static void Free( idFile* fp ) {
fileSystem->CloseFile( fp );
}
};
typedef sdAutoPtr< idFile, sdCleanupPolicy_CloseFile > sdFilePtr;
typedef sdAutoPtr< idFile_Memory, sdCleanupPolicy_CloseFile > sdFileMemoryPtr;
// idLib versions
struct sdCleanupPolicy_idLibCloseFile {
static void Free( idFile* fp ) {
idLib::fileSystem->CloseFile( fp );
}
};
typedef sdAutoPtr< idFile, sdCleanupPolicy_idLibCloseFile > sdLibFilePtr;
typedef sdAutoPtr< idFile_Memory, sdCleanupPolicy_idLibCloseFile > sdLibFileMemoryPtr;
#endif /* !__FILESYSTEM_H__ */