[Scummvm-git-logs] scummvm master -> 2b9244c2de2ecc4c115eccab35be98c33f050649
phcoder
noreply at scummvm.org
Thu Dec 1 00:53:30 UTC 2022
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
1d15e2a66e COMMON: Fix DisposablePtr move constructor in presence of a deleter
81040b5d20 COMMON: Make memstream support SharedPtr-backed array
b2def0293c COMMON: Add MemcachingCaseInsensitiveArchive for caching archive contents
acc709730f COMMON: Switch clickteam to MemcachingCaseInsensitiveArchive.
2521169a7b DREAMWEB: Switch RNCA archive to MemcachingCaseInsensitiveArchive.
489d83c76d MADS: Switch MpsInstaller archive to MemcachingCaseInsensitiveArchive
bb792d2c3a COMMON: Switch unarj to MemcachingCaseInsensitiveArchive
2b9244c2de COMMON: Switch unzip to MemcachingCaseInsensitiveArchive
Commit: 1d15e2a66e4524df4a922f8c3a947a773d1d5f68
https://github.com/scummvm/scummvm/commit/1d15e2a66e4524df4a922f8c3a947a773d1d5f68
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-01T01:52:46+01:00
Commit Message:
COMMON: Fix DisposablePtr move constructor in presence of a deleter
Changed paths:
common/ptr.h
diff --git a/common/ptr.h b/common/ptr.h
index 2922dbdb4e8..4f61dd9cd01 100644
--- a/common/ptr.h
+++ b/common/ptr.h
@@ -658,7 +658,7 @@ public:
explicit DisposablePtr(PointerType o, DisposeAfterUse::Flag dispose) : _pointer(o), _dispose(dispose), _shared() {}
explicit DisposablePtr(SharedPtr<T> o) : _pointer(o.get()), _dispose(DisposeAfterUse::NO), _shared(o) {}
- DisposablePtr(DisposablePtr<T>&& o) : _pointer(o._pointer), _dispose(o._dispose), _shared(o._shared) {
+ DisposablePtr(DisposablePtr<T, DL>&& o) : _pointer(o._pointer), _dispose(o._dispose), _shared(o._shared) {
o._pointer = nullptr;
o._dispose = DisposeAfterUse::NO;
o._shared.reset();
Commit: 81040b5d2064abfed69214f7f2086d518ee1e147
https://github.com/scummvm/scummvm/commit/81040b5d2064abfed69214f7f2086d518ee1e147
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-01T01:52:46+01:00
Commit Message:
COMMON: Make memstream support SharedPtr-backed array
This allows to safely implement archive contents caches.
The change to lilliput is needed to allow to keep move-constructot
semantics of ScriptStream which would otherwise disappear because
DisposablePtr is non-copyable
Changed paths:
common/memstream.h
common/stream.cpp
engines/lilliput/stream.h
diff --git a/common/memstream.h b/common/memstream.h
index 17bbc30dd8e..e787b95bb1e 100644
--- a/common/memstream.h
+++ b/common/memstream.h
@@ -42,14 +42,28 @@ namespace Common {
*/
class MemoryReadStream : virtual public SeekableReadStream {
private:
- const byte * const _ptrOrig;
+ struct CastFreeDeleter {
+ inline void operator()(const byte *object) {
+ free(const_cast<byte *>(object));
+ }
+ };
+
+ // Note when using SharedPtr, then deleting is handled
+ // by SharedPtr and not by CastFreeDeleter
+ Common::DisposablePtr<const byte, CastFreeDeleter> _ptrOrig;
const byte *_ptr;
- const uint32 _size;
+ uint32 _size;
uint32 _pos;
- DisposeAfterUse::Flag _disposeMemory;
bool _eos;
public:
+ MemoryReadStream(MemoryReadStream &&other) : _ptrOrig(Common::move(other._ptrOrig)), _ptr(other._ptr), _size(other._size), _pos(other._pos), _eos(other._eos) {
+ // other must remaining in a valid state. Let's make it into zero-sized stream.
+ other._ptr = nullptr;
+ other._size = 0;
+ other._pos = 0;
+ other._eos = false;
+ }
/**
* This constructor takes a pointer to a memory buffer and a length, and
@@ -57,17 +71,18 @@ public:
* of the buffer and hence free's it when destructed.
*/
MemoryReadStream(const byte *dataPtr, uint32 dataSize, DisposeAfterUse::Flag disposeMemory = DisposeAfterUse::NO) :
- _ptrOrig(dataPtr),
+ _ptrOrig(dataPtr, disposeMemory),
_ptr(dataPtr),
_size(dataSize),
_pos(0),
- _disposeMemory(disposeMemory),
_eos(false) {}
- ~MemoryReadStream() {
- if (_disposeMemory)
- free(const_cast<byte *>(_ptrOrig));
- }
+ MemoryReadStream(SharedPtr<byte> dataPtr, uint32 dataSize) :
+ _ptrOrig(dataPtr),
+ _ptr(dataPtr.get()),
+ _size(dataSize),
+ _pos(0),
+ _eos(false) {}
uint32 read(void *dataPtr, uint32 dataSize);
diff --git a/common/stream.cpp b/common/stream.cpp
index 80495c95581..176e35a9bb8 100644
--- a/common/stream.cpp
+++ b/common/stream.cpp
@@ -119,7 +119,7 @@ bool MemoryReadStream::seek(int64 offs, int whence) {
case SEEK_SET:
// Fall through
default:
- _ptr = _ptrOrig + offs;
+ _ptr = _ptrOrig.get() + offs;
_pos = offs;
break;
diff --git a/engines/lilliput/stream.h b/engines/lilliput/stream.h
index a191c45a675..696d5e58370 100644
--- a/engines/lilliput/stream.h
+++ b/engines/lilliput/stream.h
@@ -30,6 +30,9 @@ class ScriptStream : public Common::MemoryReadStream {
private:
byte *_orgPtr;
public:
+ ScriptStream(ScriptStream &&other) : Common::MemoryReadStream(Common::move(other)), _orgPtr(other._orgPtr) {
+ other._orgPtr = nullptr;
+ }
ScriptStream(byte *buf, int bufSize);
~ScriptStream() override;
Commit: b2def0293cb79c562f84aa9932aae0ee402a9430
https://github.com/scummvm/scummvm/commit/b2def0293cb79c562f84aa9932aae0ee402a9430
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-01T01:52:46+01:00
Commit Message:
COMMON: Add MemcachingCaseInsensitiveArchive for caching archive contents
This allows to share code for caching decompressed contents.
Changed paths:
common/archive.cpp
common/archive.h
diff --git a/common/archive.cpp b/common/archive.cpp
index 1009a7c2c9b..a61aa2fc331 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -23,6 +23,7 @@
#include "common/fs.h"
#include "common/system.h"
#include "common/textconsole.h"
+#include "common/memstream.h"
namespace Common {
@@ -60,6 +61,19 @@ int Archive::listMatchingMembers(ArchiveMemberList &list, const Path &pattern) c
return matches;
}
+SeekableReadStream *MemcachingCaseInsensitiveArchive::createReadStreamForMember(const Path &path) const {
+ String translated = translatePath(path);
+ if (!_cache.contains(translated)) {
+ _cache[translated] = readContentsForPath(translated);
+ }
+
+ const SharedArchiveContents& entry = _cache[translated];
+
+ if (entry.isFileMissing())
+ return nullptr;
+
+ return new Common::MemoryReadStream(entry.getContents(), entry.getSize());
+}
SearchSet::ArchiveNodeList::iterator SearchSet::find(const String &name) {
diff --git a/common/archive.h b/common/archive.h
index f6ab784d8c5..2e89a8e992f 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -26,6 +26,8 @@
#include "common/list.h"
#include "common/path.h"
#include "common/ptr.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
#include "common/singleton.h"
namespace Common {
@@ -139,6 +141,39 @@ public:
virtual SeekableReadStream *createReadStreamForMember(const Path &path) const = 0;
};
+class SharedArchiveContents {
+public:
+ SharedArchiveContents(byte *contents, uint32 contentSize) : _contents(contents, ArrayDeleter<byte>()), _contentSize(contentSize), _missingFile(false) {}
+ SharedArchiveContents() : _contents(nullptr), _contentSize(0), _missingFile(true) {}
+
+ bool isFileMissing() const { return _missingFile; }
+ SharedPtr<byte> getContents() const { return _contents; }
+ uint32 getSize() const { return _contentSize; }
+
+private:
+ SharedPtr<byte> _contents;
+ uint32 _contentSize;
+ bool _missingFile;
+};
+
+/**
+ * An archive that caches the resulting contents.
+ */
+class MemcachingCaseInsensitiveArchive : public Archive {
+public:
+ SeekableReadStream *createReadStreamForMember(const Path &path) const;
+
+ virtual String translatePath(const Path &path) const {
+ // Most of users of this class implement DOS-like archives.
+ // Others override this method.
+ return normalizePath(path.toString('\\'), '\\');
+ }
+
+ virtual SharedArchiveContents readContentsForPath(const String& translatedPath) const = 0;
+
+private:
+ mutable HashMap<String, SharedArchiveContents, IgnoreCase_Hash, IgnoreCase_EqualTo> _cache;
+};
/**
* The SearchSet class enables access to a group of Archives through the Archive interface.
Commit: acc709730f0cd86d418ac77fd93836c28f1eb74b
https://github.com/scummvm/scummvm/commit/acc709730f0cd86d418ac77fd93836c28f1eb74b
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-01T01:52:46+01:00
Commit Message:
COMMON: Switch clickteam to MemcachingCaseInsensitiveArchive.
Changed paths:
common/clickteam.cpp
common/clickteam.h
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<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);
}
}
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<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*/;
};
}
Commit: 2521169a7b8c840c9fe435aaad83601541f7e0fa
https://github.com/scummvm/scummvm/commit/2521169a7b8c840c9fe435aaad83601541f7e0fa
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-01T01:52:46+01:00
Commit Message:
DREAMWEB: Switch RNCA archive to MemcachingCaseInsensitiveArchive.
Changed paths:
engines/dreamweb/rnca_archive.cpp
engines/dreamweb/rnca_archive.h
diff --git a/engines/dreamweb/rnca_archive.cpp b/engines/dreamweb/rnca_archive.cpp
index 242207db4d5..7b29851b366 100644
--- a/engines/dreamweb/rnca_archive.cpp
+++ b/engines/dreamweb/rnca_archive.cpp
@@ -67,12 +67,8 @@ RNCAArchive* RNCAArchive::open(Common::SeekableReadStream *stream, DisposeAfterU
return new RNCAArchive(files, stream, dispose);
}
-static Common::String translateName(const Common::Path &path) {
- return Common::normalizePath(path.toString('\\'), '\\');
-}
-
bool RNCAArchive::hasFile(const Common::Path &path) const {
- return _files.contains(translateName(path));
+ return _files.contains(translatePath(path));
}
int RNCAArchive::listMembers(Common::ArchiveMemberList &list) const {
@@ -84,32 +80,21 @@ int RNCAArchive::listMembers(Common::ArchiveMemberList &list) const {
}
const Common::ArchiveMemberPtr RNCAArchive::getMember(const Common::Path &path) const {
- Common::String translated = translateName(path);
+ Common::String translated = translatePath(path);
if (!_files.contains(translated))
return nullptr;
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(_files.getVal(translated)._fileName, this));
}
-// TODO: Make streams stay valid after destruction of archive
-Common::SeekableReadStream *RNCAArchive::createReadStreamForMember(const Common::Path &path) const {
- Common::String translated = translateName(path);
+Common::SharedArchiveContents RNCAArchive::readContentsForPath(const Common::String& translated) const {
if (!_files.contains(translated))
- return nullptr;
+ return Common::SharedArchiveContents();
const RNCAFileDescriptor& desc = _files.getVal(translated);
- if (_cache.contains(desc._fileName)) {
- const Common::SharedPtr<CacheEntry> &entry = _cache[desc._fileName];
- if (entry->is_error) {
- return nullptr;
- }
- return new Common::MemoryReadStream(entry->contents, entry->size, DisposeAfterUse::NO);
- }
-
_stream->seek(desc._fileDataOffset);
if (_stream->readUint32BE() != Common::RncDecoder::kRnc1Signature) {
- _cache[desc._fileName] = CacheEntry::error();
- return nullptr;
+ return Common::SharedArchiveContents();
}
// Read unpacked/packed file length
@@ -117,9 +102,8 @@ Common::SeekableReadStream *RNCAArchive::createReadStreamForMember(const Common:
uint32 packLen = _stream->readUint32BE();
if (unpackLen > 0x7ffff000 || packLen > 0x7ffff000) {
- _cache[desc._fileName] = CacheEntry::error();
debug("Header error for %s", desc._fileName.c_str());
- return nullptr;
+ return Common::SharedArchiveContents();
}
// Rewind back the header
@@ -128,18 +112,16 @@ Common::SeekableReadStream *RNCAArchive::createReadStreamForMember(const Common:
byte *compressedBuffer = new byte[packLen];
if (_stream->read(compressedBuffer, packLen) != packLen) {
- _cache[desc._fileName] = CacheEntry::error();
debug("Read error for %s", desc._fileName.c_str());
- return nullptr;
+ return Common::SharedArchiveContents();
}
byte *uncompressedBuffer = new byte[unpackLen];
Common::RncDecoder rnc;
if (rnc.unpackM1(compressedBuffer, packLen, uncompressedBuffer) != (int32) unpackLen) {
- _cache[desc._fileName] = CacheEntry::error();
debug("Unpacking error for %s", desc._fileName.c_str());
- return nullptr;
+ return Common::SharedArchiveContents();
}
byte b = 0;
@@ -147,13 +129,8 @@ Common::SeekableReadStream *RNCAArchive::createReadStreamForMember(const Common:
b += *ptr;
*ptr = b;
}
-
- _cache[desc._fileName].reset(new CacheEntry);
- _cache[desc._fileName]->size = unpackLen;
- _cache[desc._fileName]->is_error = false;
- _cache[desc._fileName]->contents = uncompressedBuffer;
- return new Common::MemoryReadStream(uncompressedBuffer, unpackLen, DisposeAfterUse::NO);
+ return Common::SharedArchiveContents(uncompressedBuffer, unpackLen);
}
} // End of namespace DreamWeb
diff --git a/engines/dreamweb/rnca_archive.h b/engines/dreamweb/rnca_archive.h
index 49033330508..e808f8d6972 100644
--- a/engines/dreamweb/rnca_archive.h
+++ b/engines/dreamweb/rnca_archive.h
@@ -29,12 +29,12 @@
#include "common/hash-str.h"
namespace DreamWeb {
-class RNCAArchive : public Common::Archive {
+class RNCAArchive : public Common::MemcachingCaseInsensitiveArchive {
public:
bool hasFile(const Common::Path &path) const override;
int listMembers(Common::ArchiveMemberList&) const override;
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
- Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
+ Common::SharedArchiveContents readContentsForPath(const Common::String& translated) const override;
static RNCAArchive* open(Common::SeekableReadStream *stream, DisposeAfterUse::Flag dispose = DisposeAfterUse::NO);
@@ -53,25 +53,6 @@ private:
RNCAFileDescriptor() : _fileDataOffset(0) {}
};
- struct CacheEntry {
- byte *contents;
- uint32 size;
- bool is_error;
-
- ~CacheEntry() {
- delete[] contents;
- }
-
- static Common::SharedPtr<CacheEntry> error() {
- Common::SharedPtr<CacheEntry> ret(new CacheEntry());
- ret->size = 0;
- ret->is_error = true;
- ret->contents = nullptr;
-
- return ret;
- }
- };
-
typedef Common::HashMap<Common::String, RNCAFileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
RNCAArchive(FileMap files, Common::SeekableReadStream *stream, DisposeAfterUse::Flag dispose)
@@ -80,7 +61,6 @@ private:
FileMap _files;
Common::DisposablePtr<Common::SeekableReadStream> _stream;
- mutable Common::HashMap<Common::String, Common::SharedPtr<CacheEntry>, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _cache;
};
}
#endif
Commit: 489d83c76d20677ae8cab8b16c070e3637aa129d
https://github.com/scummvm/scummvm/commit/489d83c76d20677ae8cab8b16c070e3637aa129d
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-01T01:52:46+01:00
Commit Message:
MADS: Switch MpsInstaller archive to MemcachingCaseInsensitiveArchive
Changed paths:
engines/mads/mps_installer.cpp
engines/mads/mps_installer.h
diff --git a/engines/mads/mps_installer.cpp b/engines/mads/mps_installer.cpp
index 44639ebed26..6d6e07a94cf 100644
--- a/engines/mads/mps_installer.cpp
+++ b/engines/mads/mps_installer.cpp
@@ -63,13 +63,8 @@ MpsInstaller* MpsInstaller::open(const Common::Path& baseName) {
return new MpsInstaller(_files, baseName);
}
-// Use of \\ as path separator is a guess. Never seen an archive with subfolders
-static Common::String translateName(const Common::Path &path) {
- return Common::normalizePath(path.toString('\\'), '\\');
-}
-
bool MpsInstaller::hasFile(const Common::Path &path) const {
- return _files.contains(translateName(path));
+ return _files.contains(translatePath(path));
}
int MpsInstaller::listMembers(Common::ArchiveMemberList &list) const {
@@ -81,26 +76,21 @@ int MpsInstaller::listMembers(Common::ArchiveMemberList &list) const {
}
const Common::ArchiveMemberPtr MpsInstaller::getMember(const Common::Path &path) const {
- Common::String translated = translateName(path);
+ Common::String translated = translatePath(path);
if (!_files.contains(translated))
return nullptr;
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(_files.getVal(translated)._fileName, this));
}
-// TODO: Make streams stay valid after destruction of archive
-Common::SeekableReadStream *MpsInstaller::createReadStreamForMember(const Common::Path &path) const {
- Common::String translated = translateName(path);
+Common::SharedArchiveContents MpsInstaller::readContentsForPath(const Common::String& translated) const {
if (!_files.contains(translated))
- return nullptr;
+ return Common::SharedArchiveContents();
FileDescriptor desc = _files.getVal(translated);
- if (_cache.contains(desc._fileName)) {
- return new Common::MemoryReadStream(_cache[desc._fileName].get(), desc._uncompressedSize, DisposeAfterUse::NO);
- }
if (desc._compressionAlgo != 0 && desc._compressionAlgo != 1) {
debug ("Unsupported compression algorithm %d for %s", desc._compressionAlgo, desc._fileName.c_str());
- return nullptr;
+ return Common::SharedArchiveContents();
}
@@ -115,14 +105,14 @@ Common::SeekableReadStream *MpsInstaller::createReadStreamForMember(const Common
if (!fvol.open(volumePath)) {
error("Failed to open volume %s.%03d", volumePath.toString().c_str(), vol);
delete[] compressedBuf;
- return nullptr;
+ return Common::SharedArchiveContents();
}
fvol.seek(off);
int32 actual = fvol.read(outptr, rem);
if (actual <= 0) {
warning("Read failure in volume %s.%03d", volumePath.toString().c_str(), vol);
delete[] compressedBuf;
- return nullptr;
+ return Common::SharedArchiveContents();
}
rem -= actual;
@@ -148,7 +138,7 @@ Common::SeekableReadStream *MpsInstaller::createReadStreamForMember(const Common
delete[] compressedBuf;
delete[] uncompressedBuf;
error("Unable to decompress %s", desc._fileName.c_str());
- return nullptr;
+ return Common::SharedArchiveContents();
}
delete[] compressedBuf;
compressedBuf = nullptr;
@@ -156,8 +146,7 @@ Common::SeekableReadStream *MpsInstaller::createReadStreamForMember(const Common
break;
}
- _cache[desc._fileName].reset(uncompressedBuf);
// TODO: Make it configurable to read directly from disk, at least in the uncompressed case
- return new Common::MemoryReadStream(uncompressedBuf, desc._uncompressedSize, DisposeAfterUse::NO);
+ return Common::SharedArchiveContents(uncompressedBuf, desc._uncompressedSize);
}
}
diff --git a/engines/mads/mps_installer.h b/engines/mads/mps_installer.h
index 630ed8c3ca0..487ffa076c1 100644
--- a/engines/mads/mps_installer.h
+++ b/engines/mads/mps_installer.h
@@ -30,12 +30,12 @@
namespace MADS {
-class MpsInstaller : public Common::Archive {
+class MpsInstaller : public Common::MemcachingCaseInsensitiveArchive {
public:
bool hasFile(const Common::Path &path) const override;
int listMembers(Common::ArchiveMemberList&) const override;
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
- Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
+ Common::SharedArchiveContents readContentsForPath(const Common::String& translatedPath) const override;
static MpsInstaller* open(const Common::Path& baseName);
@@ -79,7 +79,6 @@ private:
const Common::Path& baseName) : _files(files), _baseName(baseName) {}
FileMap _files;
- mutable Common::HashMap<Common::String, Common::ScopedPtr<byte, Common::ArrayDeleter<byte>>, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _cache;
Common::Path _baseName;
};
}
Commit: bb792d2c3a8f170a9a77a0679466c8bdda89e97b
https://github.com/scummvm/scummvm/commit/bb792d2c3a8f170a9a77a0679466c8bdda89e97b
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-01T01:52:46+01:00
Commit Message:
COMMON: Switch unarj to MemcachingCaseInsensitiveArchive
Changed paths:
common/unarj.cpp
diff --git a/common/unarj.cpp b/common/unarj.cpp
index c4e25f8f6c6..f580124d123 100644
--- a/common/unarj.cpp
+++ b/common/unarj.cpp
@@ -699,7 +699,7 @@ struct ArjFileChunk {
typedef HashMap<String, Array<ArjFileChunk>, IgnoreCase_Hash, IgnoreCase_EqualTo> ArjHeadersMap;
-class ArjArchive : public Archive {
+class ArjArchive : public MemcachingCaseInsensitiveArchive {
ArjHeadersMap _headers;
Array<String> _arjFilenames;
@@ -711,7 +711,10 @@ public:
bool hasFile(const Path &path) const override;
int listMembers(ArchiveMemberList &list) 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;
+ Common::String translatePath(const Common::Path &path) const override {
+ return path.toString();
+ }
};
ArjArchive::~ArjArchive() {
@@ -780,10 +783,9 @@ const ArchiveMemberPtr ArjArchive::getMember(const Path &path) const {
return ArchiveMemberPtr(new GenericArchiveMember(name, this));
}
-SeekableReadStream *ArjArchive::createReadStreamForMember(const Path &path) const {
- String name = path.toString();
+Common::SharedArchiveContents ArjArchive::readContentsForPath(const Common::String& name) const {
if (!_headers.contains(name)) {
- return nullptr;
+ return Common::SharedArchiveContents();
}
const Array <ArjFileChunk>& hdrs = _headers[name];
@@ -800,13 +802,12 @@ SeekableReadStream *ArjArchive::createReadStreamForMember(const Path &path) cons
// Prevent overflows
if (uncompressedSize > 0x70000000)
- return nullptr;
+ return Common::SharedArchiveContents();
// TODO: It would be good if ArjFile could decompress files in a streaming
// mode, so it would not need to pre-allocate the entire output.
- byte *uncompressedData = (byte *)malloc(uncompressedSize);
+ byte *uncompressedData = new byte[uncompressedSize];
uint32 uncompressedPtr = 0;
- assert(uncompressedData);
for (uint chunk = 0; chunk < totalChunks; chunk++) {
File archiveFile;
@@ -837,7 +838,7 @@ SeekableReadStream *ArjArchive::createReadStreamForMember(const Path &path) cons
uncompressedPtr += hdr->origSize;
}
- return new MemoryReadStream(uncompressedData, uncompressedSize, DisposeAfterUse::YES);
+ return Common::SharedArchiveContents(uncompressedData, uncompressedSize);
}
Archive *makeArjArchive(const String &name) {
Commit: 2b9244c2de2ecc4c115eccab35be98c33f050649
https://github.com/scummvm/scummvm/commit/2b9244c2de2ecc4c115eccab35be98c33f050649
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-01T01:52:46+01:00
Commit Message:
COMMON: Switch unzip to MemcachingCaseInsensitiveArchive
Changed paths:
common/unzip.cpp
diff --git a/common/unzip.cpp b/common/unzip.cpp
index 58132fb41b6..f22fe3c4df3 100644
--- a/common/unzip.cpp
+++ b/common/unzip.cpp
@@ -219,7 +219,7 @@ int unzGetCurrentFileInfo(unzFile file,
from it, and close it (you can close it before reading all the file)
*/
-Common::SeekableReadStream *unzOpenCurrentFile(unzFile file, const Common::CRC32& crc);
+Common::SharedArchiveContents unzOpenCurrentFile(unzFile file, const Common::CRC32& crc);
/*
Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK.
@@ -902,31 +902,30 @@ static int unzlocal_CheckCurrentFileCoherencyHeader(unz_s *s, uInt *piSizeVar,
Open for reading data the current file in the zipfile.
If there is no error and the file is opened, the return value is UNZ_OK.
*/
-Common::SeekableReadStream *unzOpenCurrentFile (unzFile file, const Common::CRC32 &crc) {
+Common::SharedArchiveContents unzOpenCurrentFile (unzFile file, const Common::CRC32 &crc) {
uInt iSizeVar;
unz_s *s;
uLong offset_local_extrafield; /* offset of the local extra field */
uInt size_local_extrafield; /* size of the local extra field */
if (file == nullptr)
- return nullptr;
+ return Common::SharedArchiveContents();
s = (unz_s *)file;
if (!s->current_file_ok)
- return nullptr;
+ return Common::SharedArchiveContents();
if (unzlocal_CheckCurrentFileCoherencyHeader(s, &iSizeVar,
&offset_local_extrafield, &size_local_extrafield) != UNZ_OK)
- return nullptr;
+ return Common::SharedArchiveContents();
if (s->cur_file_info.compression_method != 0 && s->cur_file_info.compression_method != Z_DEFLATED) {
warning("Unknown compression algoritthm %d", (int)s->cur_file_info.compression_method);
- return nullptr;
+ return Common::SharedArchiveContents();
}
uint32 crc32_wait = s->cur_file_info.crc;
- byte *compressedBuffer = (byte *)malloc(s->cur_file_info.compressed_size);
- assert(s->cur_file_info.compressed_size == 0 || compressedBuffer != nullptr);
+ byte *compressedBuffer = new byte[s->cur_file_info.compressed_size];
s->_stream->seek(s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar);
s->_stream->read(compressedBuffer, s->cur_file_info.compressed_size);
byte *uncompressedBuffer = nullptr;
@@ -936,33 +935,33 @@ Common::SeekableReadStream *unzOpenCurrentFile (unzFile file, const Common::CRC3
uncompressedBuffer = compressedBuffer;
break;
case Z_DEFLATED:
- uncompressedBuffer = (byte *)malloc(s->cur_file_info.uncompressed_size);
+ uncompressedBuffer = new byte[s->cur_file_info.uncompressed_size];
assert(s->cur_file_info.uncompressed_size == 0 || uncompressedBuffer != nullptr);
Common::GzioReadStream::deflateDecompress(uncompressedBuffer, s->cur_file_info.uncompressed_size, compressedBuffer, s->cur_file_info.compressed_size);
- free(compressedBuffer);
+ delete[] compressedBuffer;
compressedBuffer = nullptr;
break;
default:
warning("Unknown compression algoritthm %d", (int)s->cur_file_info.compression_method);
- free(compressedBuffer);
- return nullptr;
+ delete[] compressedBuffer;
+ return Common::SharedArchiveContents();
}
uint32 crc32_data = crc.crcFast(uncompressedBuffer, s->cur_file_info.uncompressed_size);
if (crc32_data != crc32_wait) {
- free(uncompressedBuffer);
+ delete[] uncompressedBuffer;
warning("CRC32 mismatch: %08x, %08x", crc32_data, crc32_wait);
- return nullptr;
+ return Common::SharedArchiveContents();
}
- return new Common::MemoryReadStream(uncompressedBuffer, s->cur_file_info.uncompressed_size, DisposeAfterUse::YES);
+ return Common::SharedArchiveContents(uncompressedBuffer, s->cur_file_info.uncompressed_size);
}
namespace Common {
-class ZipArchive : public Archive {
+class ZipArchive : public MemcachingCaseInsensitiveArchive {
unzFile _zipFile;
Common::CRC32 _crc;
@@ -975,7 +974,10 @@ public:
bool hasFile(const Path &path) const override;
int listMembers(ArchiveMemberList &list) 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;
+ Common::String translatePath(const Common::Path &path) const override {
+ return path.toString();
+ }
};
/*
@@ -1030,10 +1032,9 @@ const ArchiveMemberPtr ZipArchive::getMember(const Path &path) const {
return ArchiveMemberPtr(new GenericArchiveMember(name, this));
}
-SeekableReadStream *ZipArchive::createReadStreamForMember(const Path &path) const {
- String name = path.toString();
+Common::SharedArchiveContents ZipArchive::readContentsForPath(const Common::String& name) const {
if (unzLocateFile(_zipFile, name.c_str(), 2) != UNZ_OK)
- return nullptr;
+ return Common::SharedArchiveContents();
return unzOpenCurrentFile(_zipFile, _crc);
}
More information about the Scummvm-git-logs
mailing list