diff options
author | Matthew Hoops | 2012-05-28 16:54:49 -0400 |
---|---|---|
committer | Matthew Hoops | 2012-05-28 16:54:49 -0400 |
commit | ab45e72e67c7effae9a9fecbaf5a77f9427d8df4 (patch) | |
tree | 344bc13beb3fddce3134aa0cb953b1523c133251 /engines | |
parent | f7e515a361dac041e6693ed9a1056df6ad05975e (diff) | |
download | scummvm-rg350-ab45e72e67c7effae9a9fecbaf5a77f9427d8df4.tar.gz scummvm-rg350-ab45e72e67c7effae9a9fecbaf5a77f9427d8df4.tar.bz2 scummvm-rg350-ab45e72e67c7effae9a9fecbaf5a77f9427d8df4.zip |
COMMON: Move InstallShield code to common
The code also now works for both data compressed with sync bytes and without
Diffstat (limited to 'engines')
-rw-r--r-- | engines/agos/installshield_cab.cpp | 220 | ||||
-rw-r--r-- | engines/agos/installshield_cab.h | 41 | ||||
-rw-r--r-- | engines/agos/module.mk | 1 | ||||
-rw-r--r-- | engines/agos/res.cpp | 8 |
4 files changed, 6 insertions, 264 deletions
diff --git a/engines/agos/installshield_cab.cpp b/engines/agos/installshield_cab.cpp deleted file mode 100644 index d4e636f7b3..0000000000 --- a/engines/agos/installshield_cab.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -// The following code is based on unshield -// Original copyright: - -// Copyright (c) 2003 David Eriksson <twogood@users.sourceforge.net> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#include "agos/installshield_cab.h" - -#include "common/debug.h" -#include "common/file.h" -#include "common/memstream.h" -#include "common/zlib.h" - -namespace AGOS { - -class InstallShieldCabinet : public Common::Archive { - Common::String _installShieldFilename; - -public: - InstallShieldCabinet(const Common::String &filename); - ~InstallShieldCabinet(); - - // Common::Archive API implementation - bool hasFile(const Common::String &name) const; - int listMembers(Common::ArchiveMemberList &list) const; - const Common::ArchiveMemberPtr getMember(const Common::String &name) const; - Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; - -private: - struct FileEntry { - uint32 uncompressedSize; - uint32 compressedSize; - uint32 offset; - uint16 flags; - }; - - typedef Common::HashMap<Common::String, FileEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap; - FileMap _map; -}; - -InstallShieldCabinet::~InstallShieldCabinet() { - _map.clear(); -} - -InstallShieldCabinet::InstallShieldCabinet(const Common::String &filename) : _installShieldFilename(filename) { - Common::File installShieldFile; - - if (!installShieldFile.open(_installShieldFilename)) { - warning("InstallShieldCabinet::InstallShieldCabinet(): Could not find the archive file %s", _installShieldFilename.c_str()); - return; - } - - // Note that we only support a limited subset of cabinet files - // Only single cabinet files and ones without data shared between - // cabinets. - - // Check for the magic uint32 - if (installShieldFile.readUint32LE() != 0x28635349) { - warning("InstallShieldCabinet::InstallShieldCabinet(): Magic ID doesn't match"); - return; - } - - uint32 version = installShieldFile.readUint32LE(); - - if (version != 0x01000004) { - warning("Unsupported CAB version %08x", version); - return; - } - - /* uint32 volumeInfo = */ installShieldFile.readUint32LE(); - uint32 cabDescriptorOffset = installShieldFile.readUint32LE(); - /* uint32 cabDescriptorSize = */ installShieldFile.readUint32LE(); - - installShieldFile.seek(cabDescriptorOffset); - - installShieldFile.skip(12); - uint32 fileTableOffset = installShieldFile.readUint32LE(); - installShieldFile.skip(4); - uint32 fileTableSize = installShieldFile.readUint32LE(); - uint32 fileTableSize2 = installShieldFile.readUint32LE(); - uint32 directoryCount = installShieldFile.readUint32LE(); - installShieldFile.skip(8); - uint32 fileCount = installShieldFile.readUint32LE(); - - if (fileTableSize != fileTableSize2) - warning("file table sizes do not match"); - - // We're ignoring file groups and components since we - // should not need them. Moving on to the files... - - installShieldFile.seek(cabDescriptorOffset + fileTableOffset); - uint32 fileTableCount = directoryCount + fileCount; - uint32 *fileTableOffsets = new uint32[fileTableCount]; - for (uint32 i = 0; i < fileTableCount; i++) - fileTableOffsets[i] = installShieldFile.readUint32LE(); - - for (uint32 i = directoryCount; i < fileCount + directoryCount; i++) { - installShieldFile.seek(cabDescriptorOffset + fileTableOffset + fileTableOffsets[i]); - uint32 nameOffset = installShieldFile.readUint32LE(); - /* uint32 directoryIndex = */ installShieldFile.readUint32LE(); - - // First read in data needed by us to get at the file data - FileEntry entry; - entry.flags = installShieldFile.readUint16LE(); - entry.uncompressedSize = installShieldFile.readUint32LE(); - entry.compressedSize = installShieldFile.readUint32LE(); - installShieldFile.skip(20); - entry.offset = installShieldFile.readUint32LE(); - - // Then let's get the string - installShieldFile.seek(cabDescriptorOffset + fileTableOffset + nameOffset); - Common::String fileName; - - char c = installShieldFile.readByte(); - while (c) { - fileName += c; - c = installShieldFile.readByte(); - } - _map[fileName] = entry; - } - - delete[] fileTableOffsets; -} - -bool InstallShieldCabinet::hasFile(const Common::String &name) const { - return _map.contains(name); -} - -int InstallShieldCabinet::listMembers(Common::ArchiveMemberList &list) const { - for (FileMap::const_iterator it = _map.begin(); it != _map.end(); it++) - list.push_back(getMember(it->_key)); - - return _map.size(); -} - -const Common::ArchiveMemberPtr InstallShieldCabinet::getMember(const Common::String &name) const { - return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); -} - -Common::SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(const Common::String &name) const { - if (!_map.contains(name)) - return 0; - - const FileEntry &entry = _map[name]; - - Common::File archiveFile; - archiveFile.open(_installShieldFilename); - archiveFile.seek(entry.offset); - - if (!(entry.flags & 0x04)) { - // Not compressed - return archiveFile.readStream(entry.uncompressedSize); - } - -#ifdef USE_ZLIB - byte *src = (byte *)malloc(entry.compressedSize); - byte *dst = (byte *)malloc(entry.uncompressedSize); - - archiveFile.read(src, entry.compressedSize); - - bool result = Common::inflateZlibHeaderless(dst, entry.uncompressedSize, src, entry.compressedSize); - free(src); - - if (!result) { - warning("failed to inflate CAB file '%s'", name.c_str()); - free(dst); - return 0; - } - - return new Common::MemoryReadStream(dst, entry.uncompressedSize, DisposeAfterUse::YES); -#else - warning("zlib required to extract compressed CAB file '%s'", name.c_str()); - return 0; -#endif -} - -Common::Archive *makeInstallShieldArchive(const Common::String &name) { - return new InstallShieldCabinet(name); -} - -} // End of namespace AGOS diff --git a/engines/agos/installshield_cab.h b/engines/agos/installshield_cab.h deleted file mode 100644 index f7e8bed277..0000000000 --- a/engines/agos/installshield_cab.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "common/archive.h" -#include "common/str.h" - -#ifndef AGOS_INSTALLSHIELD_CAB_H -#define AGOS_INSTALLSHIELD_CAB_H - -namespace AGOS { - -/** - * This factory method creates an Archive instance corresponding to the content - * of the InstallShield compressed file with the given name. - * - * May return 0 in case of a failure. - */ -Common::Archive *makeInstallShieldArchive(const Common::String &name); - -} // End of namespace AGOS - -#endif diff --git a/engines/agos/module.mk b/engines/agos/module.mk index 7ae5e17bf2..7069d8005b 100644 --- a/engines/agos/module.mk +++ b/engines/agos/module.mk @@ -51,7 +51,6 @@ ifdef ENABLE_AGOS2 MODULE_OBJS += \ animation.o \ feeble.o \ - installshield_cab.o \ oracle.o \ script_dp.o \ script_ff.o \ diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp index 0305879390..2e44a6575c 100644 --- a/engines/agos/res.cpp +++ b/engines/agos/res.cpp @@ -23,6 +23,8 @@ // Resource file routines for Simon1/Simon2 +#include "common/archive.h" +#include "common/installshield_cab.h" #include "common/file.h" #include "common/memstream.h" #include "common/textconsole.h" @@ -31,7 +33,6 @@ #include "agos/agos.h" #include "agos/intern.h" #include "agos/sound.h" -#include "agos/installshield_cab.h" #include "common/zlib.h" @@ -43,7 +44,10 @@ ArchiveMan::ArchiveMan() { #ifdef ENABLE_AGOS2 void ArchiveMan::registerArchive(const Common::String &filename, int priority) { - add(filename, makeInstallShieldArchive(filename), priority); + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(filename); + + if (stream) + add(filename, makeInstallShieldArchive(stream, DisposeAfterUse::YES), priority); } #endif |