Skip to content

Commit

Permalink
Refactor|FS: Continued refactoring the libdeng1 file system
Browse files Browse the repository at this point in the history
AbstractFile is now a pure abstract class and nearly all filetype_t
switches have been replaced with virtual function calls.

Also spent a little time beginning to unwind file system traversals
previously implemented with *Iterate() function callback mechanics.

Todo: Split up AbstractFile into a set of interfaces and/or extract
functionality into subcomponents.
  • Loading branch information
danij-deng committed Oct 5, 2012
1 parent 3d1706e commit 42fe201
Show file tree
Hide file tree
Showing 20 changed files with 1,085 additions and 772 deletions.
8 changes: 0 additions & 8 deletions doomsday/engine/api/dfile.h
Expand Up @@ -115,10 +115,6 @@ class DFile
*/
DFile& rewind();

#if _DEBUG
static void debugPrint(DFile const& hndl);
#endif

friend class DFileBuilder;

private:
Expand Down Expand Up @@ -160,10 +156,6 @@ size_t DFile_Seek(DFile* hndl, size_t offset, SeekMethod whence);

void DFile_Rewind(DFile* hndl);

#if _DEBUG
void DFile_DebugPrint(DFile const* file);
#endif

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
137 changes: 126 additions & 11 deletions doomsday/engine/portable/include/abstractfile.h
Expand Up @@ -52,6 +52,9 @@ typedef enum {
#ifdef __cplusplus
namespace de {

class PathDirectoryNode;
class LumpDirectory;

/**
* Abstract File. Abstract File is a core component of the filesystem
* intended for use as the base for all types of (pseudo-)file resources.
Expand All @@ -60,6 +63,9 @@ namespace de {
*/
class AbstractFile
{
private:
AbstractFile();

public:
/**
* @param type File type identifier.
Expand All @@ -72,7 +78,7 @@ class AbstractFile
/**
* Release all memory acquired for objects linked with this resource.
*/
~AbstractFile();
virtual ~AbstractFile();

/**
* @return Type of this resource @see filetype_t
Expand Down Expand Up @@ -119,26 +125,135 @@ class AbstractFile
DFile* handle();

/**
* Abstract interface (minimal, data caching interface not expected):
* Access interfaces:
*
* @todo Extract these into one or more interface classes/subcomponents.
*/

/**
* @return Number of "lumps" contained within this resource.
*/
virtual int lumpCount() { return 1; }

/**
* Read the data associated with the specified lump index into @a buffer.
* Lookup a directory node for a lump contained by this file.
*
* @param lumpIdx Lump index associated with the data being read.
* @param buffer Buffer to read into. Must be at least W_LumpLength() bytes.
* @return Number of bytes read.
* @param lumpIdx Logical index for the lump in this file's directory.
*
* @todo Should be virtual
* @return Found directory node else @c NULL if @a lumpIdx is not valid.
*/
size_t readLump(int lumpIdx, uint8_t* buffer);
virtual PathDirectoryNode* lumpDirectoryNode(int lumpIdx) = 0;

/**
* @return Number of "lumps" contained within this resource.
* Compose the absolute VFS path to a lump contained by this file.
*
* @note Always returns a valid string object. If @a lumpIdx is not valid a
* zero-length string is returned.
*
* @param lumpIdx Logical index for the lump.
* @param delimiter Delimit directory separators using this character.
*
* @return String containing the absolute path.
*/
virtual AutoStr* composeLumpPath(int lumpIdx, char delimiter = '/') = 0;

/**
* Lookup a lump info descriptor for a lump contained by this file.
*
* @param lumpIdx Logical index for the lump in this file's directory.
*
* @return Found lump info.
*/
virtual LumpInfo const* lumpInfo(int /*lumpIdx*/) { return info(); }

/**
* Lookup the uncompressed size of lump contained by this file.
*
* @param lumpIdx Logical index for the lump in this file's directory.
*
* @return Size of the lump in bytes.
*
* @note This method is intended mainly for convenience. @see lumpInfo() for
* a better method of looking up multiple @ref LumpInfo properties.
*/
virtual size_t lumpSize(int lumpIdx) = 0;

/**
* Read the data associated with lump @a lumpIdx into @a buffer.
*
* @param lumpIdx Lump index associated with the data to be read.
* @param buffer Buffer to read into. Must be at least large enough to
* contain the whole lump.
* @param tryCache @c true= try the lump cache first.
*
* @return Number of bytes read.
*
* @see lumpSize() or lumpInfo() to determine the size of buffer needed.
*/
virtual size_t readLump(int lumpIdx, uint8_t* buffer, bool tryCache = true) = 0;

/**
* Read a subsection of the data associated with lump @a lumpIdx into @a buffer.
*
* @param lumpIdx Lump index associated with the data to be read.
* @param buffer Buffer to read into. Must be at least @a length bytes.
* @param startOffset Offset from the beginning of the lump to start reading.
* @param length Number of bytes to read.
* @param tryCache @c true= try the lump cache first.
*
* @return Number of bytes read.
*/
virtual size_t readLump(int lumpIdx, uint8_t* buffer, size_t startOffset, size_t length,
bool tryCache = true) = 0;

/**
* Publish this lump to the end of the specified @a directory.
*
* @param directory Directory to publish to.
*
* @return Number of lumps published to the directory. Always @c =1
*/
virtual int publishLumpsToDirectory(LumpDirectory* directory) = 0;

/**
* Lump caching interface:
*/

/**
* Read the data associated with lump @a lumpIdx into the cache.
*
* @param lumpIdx Lump index associated with the data to be cached.
*
* @return Pointer to the cached copy of the associated data.
*/
virtual uint8_t const* cacheLump(int lumpIdx) = 0;

/**
* Remove a lock on a cached data lump.
*
* @param lumpIdx Lump index associated with the cached data to be changed.
*
* @return This instance.
*/
virtual AbstractFile& unlockLump(int lumpIdx) = 0;

/**
* Clear any cached data for lump @a lumpIdx from the lump cache.
*
* @param lumpIdx Lump index associated with the cached data to be cleared.
* @param retCleared If not @c NULL write @c true to this address if data was
* present and subsequently cleared from the cache.
*
* @return This instance.
*/
//virtual AbstractFile& clearCachedLump(int lumpIdx, bool* retCleared = 0) = 0;

/**
* Purge the lump cache, clearing all cached data lumps.
*
* @todo Should be virtual
* @return This instance.
*/
int lumpCount();
//virtual AbstractFile& clearLumpCache() = 0;

private:
/// @see filetype_t
Expand Down
152 changes: 88 additions & 64 deletions doomsday/engine/portable/include/fs_main.h
Expand Up @@ -102,41 +102,9 @@ void F_PrintFileId(byte identifier[16]);
*/
boolean F_CheckFileId(char const* path);

/// @return @c true if the FileId associated with @a path was released.
boolean F_ReleaseFileId(char const* path);

/// @return Number of files in the currently active primary LumpDirectory.
int F_LumpCount(void);

boolean F_IsValidLumpNum(lumpnum_t absoluteLumpNum);

boolean F_LumpIsCustom(lumpnum_t absoluteLumpNum);

char const* F_LumpName(lumpnum_t absoluteLumpNum);

size_t F_LumpLength(lumpnum_t absoluteLumpNum);

char const* F_LumpSourceFile(lumpnum_t absoluteLumpNum);

uint F_LumpLastModified(lumpnum_t absoluteLumpNum);

/**
* Given a logical @a lumpnum retrieve the associated file object.
*
* @post The active LumpDirectory may have changed!
*
* @param absoluteLumpNum Logical lumpnum associated to the file being looked up.
* @param lumpIdx If not @c NULL the translated lumpnum within the owning
* file object is written here.
*
* @return Found file object else @c NULL
*/
AbstractFile* F_FindFileForLumpNum2(lumpnum_t absoluteLumpNum, int* lumpIdx);
AbstractFile* F_FindFileForLumpNum(lumpnum_t absoluteLumpNum);

LumpInfo const* F_FindInfoForLumpNum2(lumpnum_t absoluteLumpNum, int* lumpIdx);
LumpInfo const* F_FindInfoForLumpNum(lumpnum_t absoluteLumpNum);

lumpnum_t F_CheckLumpNumForName2(char const* name, boolean silent);
lumpnum_t F_CheckLumpNumForName(char const* name);

Expand All @@ -150,15 +118,6 @@ lumpnum_t F_OpenAuxiliary(char const* fileName); /* baseOffset = 0 */

void F_CloseAuxiliary(void);

/**
* Find a lump in the Zip LumpDirectory.
*
* @param path Path to search for. Relative paths are made absolute if necessary.
* @param lumpIdx If not @c NULL the translated lumpnum within the owning file object is written here.
* @return File system object representing the file which contains the found lump else @c NULL.
*/
AbstractFile* F_FindLumpFile(char const* path, int* lumpIdx);

/**
* Files with a .wad extension are archived data files with multiple 'lumps',
* other files are single lumps whose base filename will become the lump name.
Expand Down Expand Up @@ -273,38 +232,103 @@ void F_GetPWADFileNames(char* buf, size_t bufSize, char const* delimiter);
*/
uint F_CRCNumber(void);

/// Clear all references to this file.
void F_ReleaseFile(AbstractFile* file);
/**
* Parm is passed on to the callback, which is called for each file
* matching the filespec. Absolute path names are given to the callback.
* Zip directory, DD_DIREC and the real files are scanned.
*
* @param flags @see searchPathFlags
*/
int F_AllResourcePaths2(char const* searchPath, int flags, int (*callback) (char const* path, PathDirectoryNodeType type, void* parameters), void* parameters);
int F_AllResourcePaths(char const* searchPath, int flags, int (*callback) (char const* path, PathDirectoryNodeType type, void* parameters)/*, parameters = 0 */);

/// Close this file.
void F_Close(DFile* file);
#ifdef __cplusplus
} // extern "C"
#endif

/// Completely destroy this file; close if open, clear references and any acquired identifiers.
void F_Delete(DFile* file);
#ifdef __cplusplus

AutoStr* F_ComposeLumpPath2(AbstractFile* file, int lumpIdx, char delimiter);
AutoStr* F_ComposeLumpPath(AbstractFile* file, int lumpIdx); /*delimiter='/'*/
namespace de {

class FS
{
public:
/**
* Find a lump in the Zip LumpDirectory.
*
* @param path Path to search for. Relative paths are made absolute if necessary.
* @param lumpIdx If not @c NULL the translated lumpnum within the owning file object is written here.
* @return File system object representing the file which contains the found lump else @c NULL.
*/
static AbstractFile* findLumpFile(char const* path, int* lumpIdx = 0);

/**
* Given a logical @a lumpnum retrieve the associated file object.
*
* @post The active LumpDirectory may have changed!
*
* @param absoluteLumpNum Logical lumpnum associated to the file being looked up.
* @param lumpIdx If not @c NULL the translated lumpnum within the owning
* file object is written here.
*
* @return Found file object else @c NULL
*/
static AbstractFile* findFileForLumpNum(lumpnum_t absoluteLumpNum, int* lumpIdx = 0);

/// Clear all references to this file.
static void releaseFile(AbstractFile* file);

/// Close this file handle.
static void closeFile(DFile* hndl);

/// Completely destroy this file; close if open, clear references and any acquired identifiers.
static void deleteFile(DFile* hndl);
};

} // namespace de

struct pathdirectorynode_s* F_LumpDirectoryNode(AbstractFile* file, int lumpIdx);
extern "C" {
#endif // __cplusplus

LumpInfo const* F_LumpInfo(AbstractFile* file, int lumpIdx);
/**
* C wrapper API:
*/

size_t F_ReadLumpSection(AbstractFile* file, int lumpIdx, uint8_t* buffer,
size_t startOffset, size_t length);
boolean F_IsValidLumpNum(lumpnum_t absoluteLumpNum);

uint8_t const* F_CacheLump(AbstractFile* file, int lumpIdx);
boolean F_LumpIsCustom(lumpnum_t absoluteLumpNum);

void F_UnlockLump(AbstractFile* file, int lumpIdx);
char const* F_LumpName(lumpnum_t absoluteLumpNum);

/**
* Parm is passed on to the callback, which is called for each file
* matching the filespec. Absolute path names are given to the callback.
* Zip directory, DD_DIREC and the real files are scanned.
*
* @param flags @see searchPathFlags
*/
int F_AllResourcePaths2(char const* searchPath, int flags, int (*callback) (ddstring_t const* path, PathDirectoryNodeType type, void* parameters), void* parameters);
int F_AllResourcePaths(char const* searchPath, int flags, int (*callback) (ddstring_t const* path, PathDirectoryNodeType type, void* parameters)/*, parameters = 0 */);
size_t F_LumpLength(lumpnum_t absoluteLumpNum);

char const* F_LumpSourceFile(lumpnum_t absoluteLumpNum);

uint F_LumpLastModified(lumpnum_t absoluteLumpNum);

LumpInfo const* F_FindInfoForLumpNum2(lumpnum_t absoluteLumpNum, int* lumpIdx);
LumpInfo const* F_FindInfoForLumpNum(lumpnum_t absoluteLumpNum);

struct abstractfile_s* F_FindFileForLumpNum2(lumpnum_t absoluteLumpNum, int* lumpIdx);
struct abstractfile_s* F_FindFileForLumpNum(lumpnum_t absoluteLumpNum/*, lumpIdx = 0 */);

void F_Close(struct dfile_s* file);

void F_Delete(struct dfile_s* file);

AutoStr* F_ComposeLumpPath2(struct abstractfile_s* file, int lumpIdx, char delimiter);
AutoStr* F_ComposeLumpPath(struct abstractfile_s* file, int lumpIdx); /*delimiter='/'*/

LumpInfo const* F_LumpInfo(struct abstractfile_s* file, int lumpIdx);

size_t F_ReadLump(struct abstractfile_s* file, int lumpIdx, uint8_t* buffer);

size_t F_ReadLumpSection(struct abstractfile_s* file, int lumpIdx, uint8_t* buffer,
size_t startOffset, size_t length);

uint8_t const* F_CacheLump(struct abstractfile_s* file, int lumpIdx);

void F_UnlockLump(struct abstractfile_s* file, int lumpIdx);

#ifdef __cplusplus
} // extern "C"
Expand Down

0 comments on commit 42fe201

Please sign in to comment.