Difference between revisions of "HOWTO-Open Files"

Jump to navigation Jump to search
110 bytes removed ,  15:17, 25 October 2018
m
Text replacement - "</source>" to "</syntaxhighlight>"
(add code samples)
m (Text replacement - "</source>" to "</syntaxhighlight>")
 
(6 intermediate revisions by 4 users not shown)
Line 9: Line 9:


The basic case: you want to open a file called "datafile.dat":
The basic case: you want to open a file called "datafile.dat":
<syntax type="C++">#include "common/file.h"
<syntaxhighlight lang="cpp">
using Common::File;
#include "common/file.h"


File* f = new File;
Common::File f;
if (!f || !f->open("datafile.dat")) {
if (!f.open("datafile.dat")) {
   // handle failure to find/open file
   // handle failure to find/open file
}
}
// access f</syntax>
// access f
</syntaxhighlight>


Or, you want to open a file called "datafile.dat" in a subdirectory "data" of the game directory:
Or, you want to open a file called "datafile.dat" in a subdirectory "data" of the game directory:
<syntax type="C++">#include "common/file.h"
<syntaxhighlight lang="cpp">
using Common::File;
#include "common/file.h"


File* f = new File;
Common::File f;
if (!f || !f->open("data/datafile.dat")) {
if (!f.open("data/datafile.dat")) {
   // handle failure to find/open file
   // handle failure to find/open file
}
}
// access f</syntax>
// access f
</syntaxhighlight>


This functions by searching through a default search path managed by the SearchManager (short: SearchMan).
This functions by searching through a default search path managed by the SearchManager (short: SearchMan).
Line 43: Line 45:
*You must not pass absolute paths to <tt>File::open()</tt>! If you must open a file using a path, the correct way is to first create an FSNode from the path, then pass that to File::open.
*You must not pass absolute paths to <tt>File::open()</tt>! If you must open a file using a path, the correct way is to first create an FSNode from the path, then pass that to File::open.
*You can pass relative paths in a limited fashion; you must use the "/" character as separator. See the doxygen docs of class FSDirectory for details.
*You can pass relative paths in a limited fashion; you must use the "/" character as separator. See the doxygen docs of class FSDirectory for details.
*There are new File::open methods: You can pass an "Archive" subclass (e.g. a ZIPArchive) to it, and it will search for that file in the Archive). In particular, the SearchMan is such an Archive subclass, and can wrap arbitrary paths, ZIP archives, etc. By providing Archive subclasses, you can extend this arbitrarily.
*There are new File::open methods: You can pass an "Archive" subclass (e.g. a ZIPArchive) to it, and it will search for that file in the Archive). In particular, the SearchMan is such an Archive subclass, and can wrap arbitrary paths, ZIP or ARJ archives, etc. By providing Archive subclasses, you can extend this arbitrarily.
 


==The Parts of the System==
==The Parts of the System==
Line 70: Line 71:


===Archive (from common/archive.h)===
===Archive (from common/archive.h)===
This class represents an accumulation of "files". It can be a filesystem directory (implemented by FSDirectory), and then "contains" all the files in that directory (and possibly also files contained some levels deep in that dir). It can be a ZIP archive (see common/unzip.h), and then the "files" in it are members of that ZIP file. It can even be an accumulation of multiple other archives, and then it contains all files contained in all of these dirs (see class SearchSet). The SearchManager is in fact just an instance of this class, too.
This class represents an accumulation of "files". It can be a filesystem directory (implemented by FSDirectory), and then "contains" all the files in that directory (and possibly also files contained some levels deep in that dir). It can be a ZIP or ARJ archive (see resp. common/unzip.h and common/unarj.h), and then the "files" in it are members of that compressed file. It can even be an accumulation of multiple other archives, and then it contains all files contained in all of these dirs (see class SearchSet). The SearchManager is in fact just an instance of this class, too.


This concept is simple yet powerful. By  using SearchSet, you can group together multiple directories and ZIP files, and then with a single call, search for files in all of them simultaneously.
This concept is simple yet powerful. By  using SearchSet, you can group together multiple directories and compressed files, and then with a single call, search for files in all of them simultaneously.


You can ask an Archive whether it contains a given file; open a file (either via the openFile() method, which returns a ReadStream pointer you have to delete later on; or via the new File::open(name, archive) method); get a list of all files in the archive; or get a list of
You can ask an Archive whether it contains a given file; open a file (either via the openFile() method, which returns a ReadStream pointer you have to delete later on; or via the new File::open(name, archive) method); get a list of all files in the archive; or get a list of
Line 90: Line 91:
Savestates are by default handled via FSNodes, too. If you need to handle savestates differently (like many console ports do), by providing a custom SavefileManager implementation (many ports do that already).
Savestates are by default handled via FSNodes, too. If you need to handle savestates differently (like many console ports do), by providing a custom SavefileManager implementation (many ports do that already).


If your port has the config file in a special location (be it in a special path, or you want to store it in the Windows registry, or in some special NVRAM, or whatever -- go nuts with ideas), you can overload OSystem::openConfigFileForReading() and OSystem::openConfigFileForWriting() methods (NOTE: Various ports already do it, but I'd wish the iPhone, PS2, PSP and PalmOS ports would finally clean out their cruft from common/system.cpp ;)
If your port has the config file in a special location (be it in a special path, or you want to store it in the Windows registry, or in some special NVRAM, or whatever -- go nuts with ideas), you can overload OSystem::openConfigFileForReading() and OSystem::openConfigFileForWriting() methods.


If you want ScummVM to look for file in additional dirs (like, on OSX, we store the engine-data files like sky.cpt and kyra.dat inside the application bundle), your port can overload the OSystem::addSysArchivesToSearchSet() method to hook these extra locations into the SearchMan -- this way, the location is checked whenever the default File::open method is used, for example. You can hook up arbitrary Archive classes here (even .zip files), not just directories, so it's quite flexible.
If you want ScummVM to look for file in additional dirs (like, on OSX, we store the engine-data files like sky.cpt and kyra.dat inside the application bundle), your port can overload the OSystem::addSysArchivesToSearchSet() method to hook these extra locations into the SearchMan -- this way, the location is checked whenever the default File::open method is used, for example. You can hook up arbitrary Archive classes here (even .ZIP or .ARJ files), not just directories, so it's quite flexible.
TrustedUser
2,147

edits

Navigation menu