diff options
| -rw-r--r-- | common/file.cpp | 52 | ||||
| -rw-r--r-- | common/file.h | 54 | ||||
| -rw-r--r-- | engines/saga/music.cpp | 7 | ||||
| -rw-r--r-- | engines/scumm/resource.cpp | 2 | 
4 files changed, 81 insertions, 34 deletions
diff --git a/common/file.cpp b/common/file.cpp index 6558dfea33..ec605d45c1 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -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; diff --git a/common/file.h b/common/file.h index a2739f795f..079b0bba84 100644 --- a/common/file.h +++ b/common/file.h @@ -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(); diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp index 5bf0c0ec03..5d0c75d0ce 100644 --- a/engines/saga/music.cpp +++ b/engines/saga/music.cpp @@ -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); diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp index 50e0d221ca..87ded6723b 100644 --- a/engines/scumm/resource.cpp +++ b/engines/scumm/resource.cpp @@ -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();  | 
