diff --git a/common/clickteam.cpp b/common/clickteam.cpp index 022522afde4..d6334cc97d3 100644 --- a/common/clickteam.cpp +++ b/common/clickteam.cpp @@ -216,12 +216,8 @@ ClickteamInstaller* ClickteamInstaller::open(Common::SeekableReadStream *stream, return new ClickteamInstaller(files, tags, crc_xor, block3_offset, block3_len, stream, dispose); } -static Common::String translateName(const Path &path) { - return Common::normalizePath(path.toString('\\'), '\\'); -} - bool ClickteamInstaller::hasFile(const Path &path) const { - return _files.contains(translateName(path)); + return _files.contains(translatePath(path)); } int ClickteamInstaller::listMembers(ArchiveMemberList &list) const { @@ -237,32 +233,27 @@ int ClickteamInstaller::listMembers(ArchiveMemberList &list) const { } const ArchiveMemberPtr ClickteamInstaller::getMember(const Path &path) const { - Common::String translated = translateName(path); + Common::String translated = translatePath(path); if (!_files.contains(translated)) return nullptr; return Common::SharedPtr(new GenericArchiveMember(_files.getVal(translated)._fileName, this)); } -// TODO: Make streams stay valid after destructing of archive -SeekableReadStream *ClickteamInstaller::createReadStreamForMember(const Path &path) const { - Common::String translated = translateName(path); +Common::SharedArchiveContents ClickteamInstaller::readContentsForPath(const Common::String& translated) const { if (!_files.contains(translated)) - return nullptr; + return Common::SharedArchiveContents(); ClickteamFileDescriptor desc = _files.getVal(translated); - if (_cache.contains(desc._fileName)) { - return new Common::MemoryReadStream(_cache[desc._fileName].get(), desc._uncompressedSize, DisposeAfterUse::NO); - } Common::SeekableReadStream *subStream = new Common::SeekableSubReadStream(_stream.get(), _block3Offset + desc._fileDataOffset, _block3Offset + desc._fileDataOffset + desc._compressedSize); if (!subStream) { debug("Decompression error"); - return nullptr; + return Common::SharedArchiveContents(); } Common::ScopedPtr uncStream(GzioReadStream::openClickteam(subStream, desc._uncompressedSize, DisposeAfterUse::YES)); if (!uncStream) { debug("Decompression error"); - return nullptr; + return Common::SharedArchiveContents(); } byte *uncompressedBuffer = new byte[desc._uncompressedSize]; @@ -271,7 +262,7 @@ SeekableReadStream *ClickteamInstaller::createReadStreamForMember(const Path &pa if (ret < 0 || ret < desc._uncompressedSize) { debug ("Decompression error"); delete[] uncompressedBuffer; - return nullptr; + return Common::SharedArchiveContents(); } if (desc._expectedCRC != 0 || !desc._fileName.equalsIgnoreCase("Uninstal.exe")) { @@ -281,13 +272,12 @@ SeekableReadStream *ClickteamInstaller::createReadStreamForMember(const Path &pa if (actualCrc != expectedCrc) { debug("CRC mismatch for %s: expected=%08x (obfuscated %08x), actual=%08x", desc._fileName.c_str(), expectedCrc, desc._expectedCRC, actualCrc); delete[] uncompressedBuffer; - return nullptr; + return Common::SharedArchiveContents(); } } - _cache[desc._fileName].reset(uncompressedBuffer); // TODO: Make it configurable to use a uncompressing substream instead - return new Common::MemoryReadStream(uncompressedBuffer, desc._uncompressedSize, DisposeAfterUse::NO); + return Common::SharedArchiveContents(uncompressedBuffer, desc._uncompressedSize); } } diff --git a/common/clickteam.h b/common/clickteam.h index aa3e67f4a50..0eecfe1a007 100644 --- a/common/clickteam.h +++ b/common/clickteam.h @@ -29,7 +29,7 @@ #include "common/hash-str.h" namespace Common { -class ClickteamInstaller : public Archive { +class ClickteamInstaller : public MemcachingCaseInsensitiveArchive { public: enum class ClickteamTagId : uint16 { BANNER_IMAGE = 0x1235, @@ -56,7 +56,7 @@ public: bool hasFile(const Path &path) const override; int listMembers(Common::ArchiveMemberList&) const override; const ArchiveMemberPtr getMember(const Path &path) const override; - SeekableReadStream *createReadStreamForMember(const Path &path) const override; + Common::SharedArchiveContents readContentsForPath(const Common::String& translated) const override; ClickteamTag* getTag(ClickteamTagId tagId) const; @@ -91,7 +91,6 @@ private: Common::HashMap _files; Common::HashMap> _tags; Common::DisposablePtr _stream; - mutable Common::HashMap>, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _cache; uint32 _crcXor, _block3Offset/*, _block3Size*/; }; }