Re: [Alephmodular-devel] TS Draft: File abstraction
Status: Pre-Alpha
Brought to you by:
brefin
|
From: Br'fin <br...@ma...> - 2003-01-27 16:02:43
|
Ok, I've done some more changes and been trying to think more things
through. Here's my updated design document for the file abstraction. :)
-Jeremy Parsons
---
Technical Specification: File Hardware Abstraction
First there was portable_files.h and it was good in concept. But there
was only a Macintosh implementation. And even so, there was an evident
bios in the structure towards the Macintosh.
Please note that this does not handle file browsing. That is in the
realm of the GUI.
Platform specific stuff can use the platform specific CFileSystemDesc
constructor.
IE Mac would support CMacFileDesc(FSSpec&)
CFileSystemDescFactory is a singleton class that provides access to a
set of base CFileSystemDesc locations.
But in order to navigate, you can't use just create a
CFileSystemDesc(...) You would need to use a factory to get an initial
CFileSystemDesc. From there you could navigate.
The factory is also the most reasonable place to provide access to
CFileSystemDescs for specific platform specific places. Ala preferences
directory and application directory
CFileSystemDesc *foo =
FILE_DESC_FACTORY-
>GetDescFor(CFileSystemDescFactory::ApplicationDirectory);
// It is an error to delete this foo
Specific directories so far are
ApplicationDirectory - The directory the application has been run from
(Current dir if command line, directory of application executable
otherwise)
PreferencesDirectory
SavedGameDirectory
ReplayDirectory
ResourcesDirectory - Where to find platform generic support files
CFileSystemDesc represents a file's location.
Under Unix, this would be the full path to a file. Under Macintosh this
is akin to a FSSpec. Most typically it refers to a parent directory and
knows the name of its file within that directory.
Most notably this has functions for creating the specified file,
opening the file for reading, or opening the file for writing.
The basic strategy for CFileSystemDesc is to create each
CFileSystemDesc as a static entity. The process of navigating based on
the CFileSystemDesc therefore doesn't modify the CFileSystemDesc, but
instead creates new CFileSystemDescs
A given platform specific derivative should accept platform native file
specifications. (For interfacing with native file browsers)
See CFileType for more about the type of the element
Basic properties (Not necessarily public!)
path that contains current element (/users/brefin/Documents)
name of current element (readme.txt)
type of current element (TEXT, txt)
One of
directory
#define SCENARIO_FILE_TYPE 'sce2'
#define SAVE_GAME_TYPE 'sga2'
#define FILM_FILE_TYPE 'fil2'
#define PHYSICS_FILE_TYPE 'phy2'
#define SHAPES_FILE_TYPE 'shp2'
#define SOUNDS_FILE_TYPE 'snd2'
#define PATCH_FILE_TYPE 'pat2'
Public Operations include
exists
is_file
is_directory
public file operations (IFileDesc) (These are errors if called on a
directory)
open_file_for_reading (Returns CFileRef)
open_file_for_writing (Returns CFileRef)
open_resource_file_for_reading (Returns CResourceFileRef)
public directory operations (IDirectoryDesc) (These are errors if
called on a file)
Stub interface for now.
Protected operations
create_file
iofname() - return an if/ofstream compatible path for the file
swap(CFileSystemDesc)
Safe Save support
Swaps contents of two file descs
These should be two files on the same device and use OS file swapping
calls where available
delete_file - accessible by friend CFileRef
Navigation of CFileSystemDescs would include methods to work based on
the CFileSystemDesc
ala CFileSystemDesc GetParent() to get the parent of this directory
and CFileSystemDesc GetNamedChild(itemname)
GetTemporaryCopy
Returns a CFileSystemDesc to a temporary file in the same directory
as the
current CFileSystemDesc, the name should be unique and the file
shouldn't already exist.
CFileRef represents an open file
Operations include
file operations are by us being either an ifstream or an ofstream
// get_fpos
// set_fpos
// set_eof
// get_file_length
// read_file
// write_file
close_file is implicit in deleting the CFileRef. Hence attempts to
fclose(CFileRef) should create a compile time error if possible.
A note on saving files. For a given FSSpec you may only have one file
open for writing. In addition, when you open a file for writing the
following transpires.
You are given an ofstream derived object that is internally associated
with the current CFileSystemDesc and a temporary one. The temporary
CFileSystemDesc is guaranteed to be in the same directory as
CFileSystemDesc and to have a unique name.
Upon proper closure of the stream the temporary file the following
happens.
If CFileSystemDesc exists, than the temporary file is swapped with it
and the original content of CFileSystemDesc discard (swap occurs, then
temporary file deleted) Otherwise the temporary file is renamed to the
name in CFileSystemDesc.
ofstream.close() isn't virtual, so we can't override it, but it does
have a virtual destructor. Within there we can do:
this->close()
if(this->is_good()) // The closing of the file didn't raise any errors
{
curFileDesc.swap(tempFileDesc);
tempFileDesc.delete();
}
IFileType represents the type of a file
CFileSystemRef is our friend and can use the protected virtual methods
for getting type_code, type_extension and the type checking.
There are two special cases of IFileType
CDirectoryType for directories
CUnknownType for CFileSystemDescs that haven't been examined yet
All others descend from CFileType which has basic operations
A file type generally encapsulates the following:
The four character code associated with a file on Macs: aka TEXT
The extension associated with the file on other systems: aka txt (as
in README.txt)
a method of checking whether or not a CFileSystemDesc matches the
current type
and returns a boolean
(grr, I can't think of a reasonable name for this method...
is_this_yours, matches_type, type_check, check_type...)
CDirectoryType only matches type with directories
CUnknownType never matches. But is only assigned when either nothing is
known, or everything else fails to match.
At any rate, the method for checking type can be expanded upon. It
doesn't just have to go by type and/or extension. It is allowed to open
and inspect the file for more info. However, there should be a toggle.
Thus letting the system do a quick first pass checking type/extension.
And then, if the file is still unknown, do the longer file inspection
checks.
FileTypes should also support an is_a operator. For instance, all map
files, no matter what type or version, should return true for
is_a(CMapType) Even though it would be an error to set any given file's
type explicitly to CMapType.
|