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. |