Added multiple new open() methods to Common::File, which make it possible to use this class as a generic convenience wrapper around all kinds of SeekableReadStream; also renamed the name() method to the less confusing getName()

svn-id: r34696
This commit is contained in:
Max Horn 2008-09-30 09:12:02 +00:00
parent d4a76c026f
commit 7c0b2cfd27
4 changed files with 81 additions and 34 deletions

View File

@ -65,61 +65,59 @@ File::~File() {
close();
}
bool File::open(const String &filename) {
return open(filename, SearchMan);
}
bool File::open(const String &filename, Archive &archive) {
assert(!filename.empty());
assert(!_handle);
_name.clear();
clearIOFailed();
if (SearchMan.hasFile(filename)) {
SeekableReadStream *stream = 0;
if (archive.hasFile(filename)) {
debug(3, "Opening hashed: %s", filename.c_str());
_handle = SearchMan.openFile(filename);
} else if (SearchMan.hasFile(filename + ".")) {
stream = archive.openFile(filename);
} else if (archive.hasFile(filename + ".")) {
// WORKAROUND: Bug #1458388: "SIMON1: Game Detection fails"
// sometimes instead of "GAMEPC" we get "GAMEPC." (note trailing dot)
debug(3, "Opening hashed: %s.", filename.c_str());
_handle = SearchMan.openFile(filename + ".");
stream = archive.openFile(filename + ".");
}
if (_handle == NULL)
debug(2, "File::open: '%s' not found", filename.c_str());
else
_name = filename;
return _handle != NULL;
return open(stream, filename);
}
bool File::open(const FilesystemNode &node) {
assert(!_handle);
if (!node.exists()) {
warning("File::open: FilesystemNode does not exist");
warning("File::open: '%s' does not exist", node.getPath().c_str());
return false;
} else if (node.isDirectory()) {
warning("File::open: FilesystemNode is a directory");
warning("File::open: '%s' is a directory", node.getPath().c_str());
return false;
}
String filename(node.getName());
if (_handle) {
error("File::open: This file object already is opened (%s), won't open '%s'", _name.c_str(), filename.c_str());
}
SeekableReadStream *stream = node.openForReading();
return open(stream, node.getPath());
}
bool File::open(SeekableReadStream *stream, const Common::String &name) {
assert(!_handle);
clearIOFailed();
_name.clear();
_handle = node.openForReading();
if (_handle == NULL)
debug(2, "File::open: '%s' not found", node.getPath().c_str());
else
_name = filename;
if (stream) {
_handle = stream;
_name = name;
} else {
debug(2, "File::open: opening '%s' failed", name.c_str());
}
return _handle != NULL;
}
bool File::exists(const String &filename) {
if (SearchMan.hasFile(filename)) {
return true;

View File

@ -27,6 +27,7 @@
#define COMMON_FILE_H
#include "common/scummsys.h"
#include "common/archive.h"
#include "common/noncopyable.h"
#include "common/str.h"
#include "common/stream.h"
@ -43,7 +44,7 @@ protected:
/** File handle to the actual file; 0 if no file is open. */
SeekableReadStream *_handle;
/** The name of this file, for debugging. */
/** The name of this file, kept for debugging purposes. */
String _name;
public:
@ -56,6 +57,7 @@ public:
static void resetDefaultDirectories();
File();
virtual ~File();
@ -64,14 +66,56 @@ public:
* (those were/are added by addDefaultDirectory and/or
* addDefaultDirectoryRecursive).
*
* @param filename: the file to check for
* @return: true if the file exists, else false
* @param filename the file to check for
* @return true if the file exists, false otherwise
*/
static bool exists(const String &filename);
/**
* Try to open the file with the given filename, by searching SearchMan.
* @note Must not be called if this file already is open (i.e. if isOpen returns true).
*
* @param filename the name of the file to open
* @return true if file was opened successfully, false otherwise
*/
virtual bool open(const String &filename);
/**
* Try to open the file with the given filename from within the given archive.
* @note Must not be called if this file already is open (i.e. if isOpen returns true).
*
* @param filename the name of the file to open
* @param archive the archive in which to search for the file
* @return true if file was opened successfully, false otherwise
*/
virtual bool open(const String &filename, Archive &archive);
/**
* Try to open the file corresponding to the give node. Will check whether the
* node actually refers to an existing file (and not a directory), and handle
* those cases gracefully.
* @note Must not be called if this file already is open (i.e. if isOpen returns true).
*
* @param filename the name of the file to open
* @param archive the archive in which to search for the file
* @return true if file was opened successfully, false otherwise
*/
virtual bool open(const FilesystemNode &node);
/**
* Try to 'open' the given stream. That is, we just wrap around it, and if stream
* is a NULL pointer, we gracefully treat this as if opening failed.
* @note Must not be called if this file already is open (i.e. if isOpen returns true).
*
* @param stream a pointer to a SeekableReadStream, or 0
* @param name a string describing the 'file' corresponding to stream
* @return true if stream was 0, false otherwise
*/
virtual bool open(SeekableReadStream *stream, const Common::String &name);
/**
* Close the file, if open.
*/
virtual void close();
/**
@ -82,11 +126,11 @@ public:
bool isOpen() const;
/**
* Returns the filename of the opened file.
* Returns the filename of the opened file for debugging purposes.
*
* @return: the filename
*/
const char *name() const { return _name.c_str(); }
const char *getName() const { return _name.c_str(); }
bool ioFailed() const;
void clearIOFailed();

View File

@ -96,7 +96,12 @@ DigitalMusicInputStream::DigitalMusicInputStream(SagaEngine *vm, ResourceContext
_compressedStream = NULL;
if (scumm_stricmp(_file->name(), "music.cmp") == 0 || scumm_stricmp(_file->name(), "musicd.cmp") == 0) {
// FIXME: It is a bad idea to use the File::getName() method to distinguish
// files here (note that it is for debugging purposes only, though that was
// not correctly documented in the past).
// A better way is to keep track of this via some flag, which indicates
// whether the music file contains compressed data.
if (scumm_stricmp(_file->getName(), "music.cmp") == 0 || scumm_stricmp(_file->getName(), "musicd.cmp") == 0) {
// Read compressed header to determine compression type
_file->seek((long)resourceData->offset, SEEK_SET);
_file->read(compressedHeader, 9);

View File

@ -676,7 +676,7 @@ int ScummEngine::loadResource(int type, int idx) {
if (tag != _res->tags[type] && _game.heversion < 70) {
error("%s %d not in room %d at %d+%d in file %s",
_res->name[type], idx, roomNr,
_fileOffset, fileOffs, _fileHandle->name());
_fileOffset, fileOffs, _fileHandle->getName());
}
size = _fileHandle->readUint32BE();