COMMON: Switch clickteam to MemcachingCaseInsensitiveArchive.

This commit is contained in:
Vladimir Serbinenko 2022-11-30 01:25:17 +01:00
parent b2def0293c
commit acc709730f
2 changed files with 11 additions and 22 deletions

View File

@ -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<Common::ArchiveMember>(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<Common::SeekableReadStream> 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);
}
}

View File

@ -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<Common::String, ClickteamFileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _files;
Common::HashMap<uint16, Common::SharedPtr<ClickteamTag>> _tags;
Common::DisposablePtr<Common::SeekableReadStream> _stream;
mutable Common::HashMap<Common::String, Common::ScopedPtr<byte, Common::ArrayDeleter<byte>>, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _cache;
uint32 _crcXor, _block3Offset/*, _block3Size*/;
};
}