diff options
-rw-r--r-- | backends/platform/sdl/sdl.cpp | 6 | ||||
-rw-r--r-- | common/archive.cpp | 13 | ||||
-rw-r--r-- | common/archive.h | 18 | ||||
-rw-r--r-- | engines/kyra/resource.cpp | 67 | ||||
-rw-r--r-- | engines/kyra/resource.h | 13 | ||||
-rw-r--r-- | engines/parallaction/disk_br.cpp | 21 | ||||
-rw-r--r-- | graphics/imageman.cpp | 2 | ||||
-rw-r--r-- | gui/ThemeEngine.cpp | 13 |
8 files changed, 87 insertions, 66 deletions
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 1c7c2fd975..be69817d5a 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -282,8 +282,7 @@ void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) // FIXME: We use depth = 4 for now, to match the old code. May want to change that Common::FSNode dataNode(DATA_PATH); if (dataNode.exists() && dataNode.isDirectory()) { - Common::ArchivePtr dataArchive(new Common::FSDirectory(dataNode, 4)); - s.add(DATA_PATH, dataArchive, priority); + s.add(DATA_PATH, new Common::FSDirectory(dataNode, 4), priority); } #endif @@ -296,8 +295,7 @@ void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) if (CFURLGetFileSystemRepresentation(fileUrl, true, buf, sizeof(buf))) { // Success: Add it to the search path Common::String bundlePath((const char *)buf); - Common::ArchivePtr bundleArchive(new Common::FSDirectory(bundlePath)); - s.add("__OSX_BUNDLE__", bundleArchive, priority); + s.add("__OSX_BUNDLE__", new Common::FSDirectory(bundlePath), priority); } CFRelease(fileUrl); } diff --git a/common/archive.cpp b/common/archive.cpp index 3c5df35326..8881d44116 100644 --- a/common/archive.cpp +++ b/common/archive.cpp @@ -281,9 +281,9 @@ void SearchSet::insert(const Node &node) { _list.insert(it, node); } -void SearchSet::add(const String& name, ArchivePtr archive, int priority) { +void SearchSet::add(const String& name, Archive *archive, int priority, bool autoFree) { if (find(name) == _list.end()) { - Node node(priority, name, archive); + Node node(priority, name, archive, autoFree); insert(node); } else { warning("SearchSet::add: archive '%s' already present", name.c_str()); @@ -294,6 +294,8 @@ void SearchSet::add(const String& name, ArchivePtr archive, int priority) { void SearchSet::remove(const String& name) { ArchiveList::iterator it = find(name); if (it != _list.end()) { + if (it->_autoFree) + delete it->_arc; _list.erase(it); } } @@ -303,6 +305,11 @@ bool SearchSet::hasArchive(const String &name) const { } void SearchSet::clear() { + for (ArchiveList::iterator i = _list.begin(); i != _list.end(); ++i) { + if (i->_autoFree) + delete i->_arc; + } + _list.clear(); } @@ -391,7 +398,7 @@ void SearchManager::addDirectory(const String &name, const FSNode &dir, int prio if (!dir.exists() || !dir.isDirectory()) return; - add(name, ArchivePtr(new FSDirectory(dir, depth)), priority); + add(name, new FSDirectory(dir, depth), priority); } void SearchManager::clear() { diff --git a/common/archive.h b/common/archive.h index 5f8cd9be60..1f29820aea 100644 --- a/common/archive.h +++ b/common/archive.h @@ -114,9 +114,6 @@ public: }; -typedef SharedPtr<Archive> ArchivePtr; - - /** * FSDirectory models a directory tree from the filesystem and allows users * to access it through the Archive interface. Searching is case-insensitive, @@ -228,11 +225,12 @@ public: */ class SearchSet : public Archive { struct Node { - int _priority; - String _name; - ArchivePtr _arc; - Node(int priority, const String &name, ArchivePtr arc) - : _priority(priority), _name(name), _arc(arc) { + int _priority; + String _name; + Archive *_arc; + bool _autoFree; + Node(int priority, const String &name, Archive *arc, bool autoFree) + : _priority(priority), _name(name), _arc(arc), _autoFree(autoFree) { } }; typedef List<Node> ArchiveList; @@ -244,10 +242,12 @@ class SearchSet : public Archive { void insert(const Node& node); public: + virtual ~SearchSet() { clear(); } + /** * Add a new archive to the searchable set. */ - void add(const String& name, ArchivePtr archive, int priority = 0); + void add(const String& name, Archive *arch, int priority = 0, bool autoFree = true); /** * Remove an archive from the searchable set. diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index c3ab6e5e70..2b09036b4e 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -35,23 +35,22 @@ namespace Kyra { -Resource::Resource(KyraEngine_v1 *vm) : _archiveCache(), _files(), _archiveFiles(new Common::SearchSet()), _protectedFiles(new Common::SearchSet()), _loaders(), _vm(vm) { +Resource::Resource(KyraEngine_v1 *vm) : _archiveCache(), _files(), _archiveFiles(), _protectedFiles(), _loaders(), _vm(vm) { initializeLoaders(); - Common::SharedPtr<Common::Archive> path(new Common::FSDirectory(ConfMan.get("path"), 2)); - Common::SharedPtr<Common::Archive> extrapath(new Common::FSDirectory(ConfMan.get("extrapath"))); - - _files.add("path", path, 4); - _files.add("extrapath", extrapath, 4); - _vm->_system->addSysArchivesToSearchSet(_files, 3); + _files.add("global_search", &Common::SearchManager::instance(), 3, false); // compressed installer archives are added at level '2', // but that's done in Resource::reset not here - _files.add("protected", _protectedFiles, 1); - _files.add("archives", _archiveFiles, 0); + _files.add("protected", &_protectedFiles, 1, false); + _files.add("archives", &_archiveFiles, 0, false); } Resource::~Resource() { _loaders.clear(); + + for (ArchiveMap::iterator i = _archiveCache.begin(); i != _archiveCache.end(); ++i) + delete i->_value; + _archiveCache.clear(); } bool Resource::reset() { @@ -68,7 +67,7 @@ bool Resource::reset() { return true; } else if (_vm->game() == GI_KYRA2) { if (_vm->gameFlags().useInstallerPackage) - _files.add("installer", loadInstallerArchive("WESTWOOD", "%03d", 6), 2); + _files.add("installer", loadInstallerArchive("WESTWOOD", "%03d", 6), 2, false); // mouse pointer, fonts, etc. required for initializing if (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie) { @@ -91,7 +90,7 @@ bool Resource::reset() { return true; } else if (_vm->game() == GI_LOL) { if (_vm->gameFlags().useInstallerPackage) - _files.add("installer", loadInstallerArchive("WESTWOOD", "%d", 0), 2); + _files.add("installer", loadInstallerArchive("WESTWOOD", "%d", 0), 2, false); return true; } @@ -114,9 +113,9 @@ bool Resource::reset() { if (fileList.empty()) error("Couldn't load PAK file '%s'", list[i]); - Common::ArchivePtr archive = loadArchive(list[i], *fileList.begin()); + Common::Archive *archive = loadArchive(list[i], *fileList.begin()); if (archive) - _protectedFiles->add(list[i], archive, 0); + _protectedFiles.add(list[i], archive, 0, false); } } else { for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { @@ -155,14 +154,14 @@ bool Resource::loadPakFile(Common::String filename) { bool Resource::loadPakFile(Common::String name, Common::SharedPtr<Common::ArchiveMember> file) { name.toUppercase(); - if (_archiveFiles->hasArchive(name) || _protectedFiles->hasArchive(name)) + if (_archiveFiles.hasArchive(name) || _protectedFiles.hasArchive(name)) return true; - Common::ArchivePtr archive = loadArchive(name, file); + Common::Archive *archive = loadArchive(name, file); if (!archive) return false; - _archiveFiles->add(name, archive, 0); + _archiveFiles.add(name, archive, 0, false); return true; } @@ -220,16 +219,24 @@ bool Resource::loadFileList(const char * const *filelist, uint32 numFiles) { void Resource::unloadPakFile(Common::String filename, bool remFromCache) { filename.toUppercase(); - _archiveFiles->remove(filename); - if (remFromCache) - _archiveCache.erase(filename); + // We do not remove files from '_protectedFiles' here, since // those are protected against unloading. + if (_archiveFiles.hasArchive(filename)) { + _archiveFiles.remove(filename); + if (remFromCache) { + ArchiveMap::iterator iter = _archiveCache.find(filename); + if (iter != _archiveCache.end()) { + delete iter->_value; + _archiveCache.erase(filename); + } + } + } } bool Resource::isInPakList(Common::String filename) { filename.toUppercase(); - return (_archiveFiles->hasArchive(filename) || _protectedFiles->hasArchive(filename)); + return (_archiveFiles.hasArchive(filename) || _protectedFiles.hasArchive(filename)); } bool Resource::isInCacheList(Common::String name) { @@ -238,8 +245,8 @@ bool Resource::isInCacheList(Common::String name) { } void Resource::unloadAllPakFiles() { - _archiveFiles->clear(); - _protectedFiles->clear(); + _archiveFiles.clear(); + _protectedFiles.clear(); } void Resource::listFiles(const Common::String &pattern, Common::ArchiveMemberList &list) { @@ -294,7 +301,7 @@ Common::SeekableReadStream *Resource::getFileStream(const Common::String &file) return _files.openFile(file); } -Common::ArchivePtr Resource::loadArchive(const Common::String &name, Common::SharedPtr<Common::ArchiveMember> member) { +Common::Archive *Resource::loadArchive(const Common::String &name, Common::SharedPtr<Common::ArchiveMember> member) { ArchiveMap::iterator cachedArchive = _archiveCache.find(name); if (cachedArchive != _archiveCache.end()) return cachedArchive->_value; @@ -302,14 +309,14 @@ Common::ArchivePtr Resource::loadArchive(const Common::String &name, Common::Sha Common::SeekableReadStream *stream = member->open(); if (!stream) - return Common::ArchivePtr(); + return 0; - Common::ArchivePtr archive; + Common::Archive *archive = 0; for (LoaderList::const_iterator i = _loaders.begin(); i != _loaders.end(); ++i) { if ((*i)->checkFilename(name)) { if ((*i)->isLoadable(name, *stream)) { stream->seek(0, SEEK_SET); - archive = Common::ArchivePtr((*i)->load(member, *stream)); + archive = (*i)->load(member, *stream); break; } else { stream->seek(0, SEEK_SET); @@ -320,20 +327,20 @@ Common::ArchivePtr Resource::loadArchive(const Common::String &name, Common::Sha delete stream; if (!archive) - return Common::ArchivePtr(); + return 0; _archiveCache[name] = archive; return archive; } -Common::ArchivePtr Resource::loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset) { +Common::Archive *Resource::loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset) { ArchiveMap::iterator cachedArchive = _archiveCache.find(file); if (cachedArchive != _archiveCache.end()) return cachedArchive->_value; - Common::ArchivePtr archive(InstallerLoader::load(this, file, ext, offset)); + Common::Archive *archive = InstallerLoader::load(this, file, ext, offset); if (!archive) - return Common::ArchivePtr(); + return 0; _archiveCache[file] = archive; return archive; diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 0831acaed6..72846e273a 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -55,8 +55,11 @@ public: bool loadPakFile(Common::String filename); bool loadPakFile(Common::String name, Common::SharedPtr<Common::ArchiveMember> file); + void unloadPakFile(Common::String filename, bool remFromCache = false); + bool isInPakList(Common::String filename); + bool isInCacheList(Common::String name); bool loadFileList(const Common::String &filedata); @@ -75,15 +78,15 @@ public: bool loadFileToBuf(const char *file, void *buf, uint32 maxSize); protected: - typedef Common::HashMap<Common::String, Common::ArchivePtr, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> ArchiveMap; + typedef Common::HashMap<Common::String, Common::Archive*, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> ArchiveMap; ArchiveMap _archiveCache; Common::SearchSet _files; - Common::SharedPtr<Common::SearchSet> _archiveFiles; - Common::SharedPtr<Common::SearchSet> _protectedFiles; + Common::SearchSet _archiveFiles; + Common::SearchSet _protectedFiles; - Common::ArchivePtr loadArchive(const Common::String &name, Common::SharedPtr<Common::ArchiveMember> member); - Common::ArchivePtr loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset); + Common::Archive *loadArchive(const Common::String &name, Common::SharedPtr<Common::ArchiveMember> member); + Common::Archive *loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset); void initializeLoaders(); diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp index 5d36076549..20b1370796 100644 --- a/engines/parallaction/disk_br.cpp +++ b/engines/parallaction/disk_br.cpp @@ -129,8 +129,7 @@ Common::String DosDisk_br::selectArchive(const Common::String& name) { debugC(5, kDebugDisk, "DosDisk_br::selectArchive: adding part directory to search set"); _sset.remove("part"); - Common::SharedPtr<Common::FSDirectory> partDir(_baseDir->getSubDirectory(name, 3)); - _sset.add("part", partDir, 10); + _sset.add("part", _baseDir->getSubDirectory(name, 3), 10); return oldPath; } @@ -149,7 +148,8 @@ void DosDisk_br::init() { // TODO: clarify whether the engine or OSystem should add the base game directory to the search manager. // Right now, I am keeping an internal search set to do the job. _baseDir = Common::SharedPtr<Common::FSDirectory>(new Common::FSDirectory(ConfMan.get("path"))); - _sset.add("base", _baseDir, 5); + // FIXME: We use this gross hack here since we switched SearchSet to accept plain pointers + _sset.add("base", _baseDir.get(), 5, false); } @@ -392,7 +392,8 @@ void DosDemoDisk_br::init() { // TODO: clarify whether the engine or OSystem should add the base game directory to the search manager. // Right now, I am keeping an internal search set to do the job. _baseDir = Common::SharedPtr<Common::FSDirectory>(new Common::FSDirectory(ConfMan.get("path"), 2)); - _sset.add("base", _baseDir, 5); + // FIXME: We use this gross hack here since we switched SearchSet to accept plain pointers + _sset.add("base", _baseDir.get(), 5, false); } @@ -413,14 +414,13 @@ AmigaDisk_br::AmigaDisk_br(Parallaction *vm) : DosDisk_br(vm) { void AmigaDisk_br::init() { _baseDir = Common::SharedPtr<Common::FSDirectory>(new Common::FSDirectory(ConfMan.get("path"))); - _sset.add("base", _baseDir, 5); + // FIXME: We use this gross hack here since we switched SearchSet to accept plain pointers + _sset.add("base", _baseDir.get(), 5, false); const Common::String subDirNames[3] = { "fonts", "backs", "common" }; const Common::String subDirPrefixes[3] = { "fonts", "backs", Common::String::emptyString }; - for (int i = 0; i < 3; i++) { - Common::SharedPtr<Common::Archive> subDir(_baseDir->getSubDirectory(subDirPrefixes[i], subDirNames[i], 2)); - _sset.add(subDirNames[i], subDir, 6); - } + for (int i = 0; i < 3; i++) + _sset.add(subDirNames[i], _baseDir->getSubDirectory(subDirPrefixes[i], subDirNames[i], 2), 6); } AmigaDisk_br::~AmigaDisk_br() { @@ -623,8 +623,7 @@ Common::String AmigaDisk_br::selectArchive(const Common::String& name) { debugC(5, kDebugDisk, "AmigaDisk_br::selectArchive: adding part directory to search set"); _sset.remove("part"); - Common::SharedPtr<Common::FSDirectory> partDir(_baseDir->getSubDirectory(name, 3)); - _sset.add("part", partDir, 10); + _sset.add("part", _baseDir->getSubDirectory(name, 3), 10); return oldPath; } diff --git a/graphics/imageman.cpp b/graphics/imageman.cpp index 1a7bcdefd1..5b7b490cd7 100644 --- a/graphics/imageman.cpp +++ b/graphics/imageman.cpp @@ -66,7 +66,7 @@ bool ImageManager::addArchive(const Common::String &name) { arch = dir; } - _archives.add(name, Common::ArchivePtr(arch)); + _archives.add(name, arch); return true; } diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 7d59720d7d..13fd1ea24d 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -525,38 +525,42 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeName) { if (!node.exists() || !node.isReadable()) return false; - Common::ArchivePtr archive; + Common::Archive *archive; if (node.getName().hasSuffix(".zip") && !node.isDirectory()) { #ifdef USE_ZLIB Common::ZipArchive *zipArchive = new Common::ZipArchive(node); - archive = Common::ArchivePtr(zipArchive); + archive = zipArchive; if (!zipArchive || !zipArchive->isOpen()) { + delete zipArchive; warning("Failed to open Zip archive '%s'.", themeName.c_str()); return false; } #endif } else if (node.isDirectory()) { - archive = Common::ArchivePtr(new Common::FSDirectory(node)); + archive = new Common::FSDirectory(node); } Common::File themercFile; themercFile.open("THEMERC", *archive); if (!themercFile.isOpen()) { + delete archive; warning("Theme '%s' contains no 'THEMERC' file.", themeName.c_str()); return false; } Common::String stxHeader = themercFile.readLine(); if (!themeConfigParseHeader(stxHeader, _themeName) || _themeName.empty()) { + delete archive; warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str()); return false; } Common::ArchiveMemberList members; if (0 == archive->listMatchingMembers(members, "*.stx")) { + delete archive; warning("Found no STX files for theme '%s'.", themeName.c_str()); return false; } @@ -566,12 +570,14 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeName) { assert((*i)->getName().hasSuffix(".stx")); if (_parser->loadStream((*i)->open()) == false) { + delete archive; warning("Failed to load STX file '%s'", (*i)->getName().c_str()); _parser->close(); return false; } if (_parser->parse() == false) { + delete archive; warning("Failed to parse STX file '%s'", (*i)->getName().c_str()); _parser->close(); return false; @@ -580,6 +586,7 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeName) { _parser->close(); } + delete archive; assert(!_themeName.empty()); return true; } |