[Scummvm-git-logs] scummvm master -> 654f7fd8d0dcdef4ff392372f2d6a56f0a3086bc
bluegr
noreply at scummvm.org
Mon Jun 19 05:45:37 UTC 2023
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
7be3c8f602 COMMON: Add "flattenTree" param to createStuffItArchive and preserve directory structure by default
e53d2ec594 COMMON: Add "getPathSeparator" to Archive and return ":" for Mac archive formats
907252ecbd COMMON: Return correct path separator for InstallShieldV3
654f7fd8d0 COMMON: Add comments on usage
Commit: 7be3c8f6028de55ddd5cca6d43aee1b943414a97
https://github.com/scummvm/scummvm/commit/7be3c8f6028de55ddd5cca6d43aee1b943414a97
Author: elasota (ejlasota at gmail.com)
Date: 2023-06-19T08:45:32+03:00
Commit Message:
COMMON: Add "flattenTree" param to createStuffItArchive and preserve directory structure by default
Changed paths:
common/compression/stuffit.cpp
common/compression/stuffit.h
engines/grim/grim.cpp
engines/groovie/groovie.cpp
engines/kyra/resource/resource_intern.cpp
engines/mtropolis/boot.cpp
engines/private/private.cpp
diff --git a/common/compression/stuffit.cpp b/common/compression/stuffit.cpp
index d869685a07b..d6011b168e2 100644
--- a/common/compression/stuffit.cpp
+++ b/common/compression/stuffit.cpp
@@ -43,8 +43,8 @@ public:
StuffItArchive();
~StuffItArchive() override;
- bool open(const Common::String &filename);
- bool open(Common::SeekableReadStream *stream);
+ bool open(const Common::String &filename, bool flattenTree);
+ bool open(Common::SeekableReadStream *stream, bool flattenTree);
void close();
bool isOpen() const { return _stream != nullptr; }
@@ -54,7 +54,7 @@ public:
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
Common::SharedArchiveContents readContentsForPath(const Common::String& name) const override;
Common::String translatePath(const Common::Path &path) const override {
- return path.toString();
+ return path.toString(':');
}
private:
@@ -99,12 +99,12 @@ static const uint32 s_magicNumbers[] = {
MKTAG('S', 'T', 'i', '3'), MKTAG('S', 'T', 'i', '4'), MKTAG('S', 'T', '4', '6')
};
-bool StuffItArchive::open(const Common::String &filename) {
+bool StuffItArchive::open(const Common::String &filename, bool flattenTree) {
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(filename);
- return open(stream);
+ return open(stream, flattenTree);
}
-bool StuffItArchive::open(Common::SeekableReadStream *stream) {
+bool StuffItArchive::open(Common::SeekableReadStream *stream, bool flattenTree) {
close();
_stream = stream;
@@ -144,7 +144,11 @@ bool StuffItArchive::open(Common::SeekableReadStream *stream) {
Common::CRC16 crc;
+ Common::String dirPrefix;
+
while (_stream->pos() < _stream->size() && !_stream->eos() && _stream->pos() < archiveSize) {
+ const uint kMaxFileLength = 31;
+
byte header[112];
_stream->read(header, sizeof(header));
Common::MemoryReadStream headStream(header, sizeof(header));
@@ -154,9 +158,10 @@ bool StuffItArchive::open(Common::SeekableReadStream *stream) {
byte fileNameLength = headStream.readByte();
Common::String name;
- if (fileNameLength > 63)
+ if (fileNameLength > kMaxFileLength)
error("File name length too long in stuffit archive: %d at 0x%x", fileNameLength, (int) (_stream->pos() - 3));
+
for (byte i = 0; i < fileNameLength; i++)
name += (char)headStream.readByte();
@@ -184,9 +189,32 @@ bool StuffItArchive::open(Common::SeekableReadStream *stream) {
if (actualHeaderCRC != headerCRC)
error ("StuffItArchive::open(): Header CRC mismatch: %04x vs %04x", actualHeaderCRC, headerCRC);
- // Ignore directories for now
- if (dataForkCompression == 32 || dataForkCompression == 33)
+ byte dirCheckMethod = (dataForkCompression & 0x6f); // Strip 0x80 (encrypted) and 0x10 (folder contents encrypted) flags
+ if (dirCheckMethod == 32) {
+ // Start of folder
+ if (!flattenTree)
+ dirPrefix = dirPrefix + name + ":";
+ continue;
+ }
+
+ if (dirCheckMethod == 33) {
+ // End of folder
+ if (!flattenTree && dirPrefix.size() > 0) {
+ size_t secondLastDelimiter = dirPrefix.rfind(':', dirPrefix.size() - 1);
+
+ if (secondLastDelimiter == Common::String::npos) {
+ // Only one level deep
+ dirPrefix.clear();
+ } else {
+ // Multiple levels deep
+ dirPrefix = dirPrefix.substr(0, secondLastDelimiter + 1);
+ }
+ }
continue;
+ }
+
+ if (!flattenTree)
+ name = dirPrefix + name;
_metadataMap[name + ".finf"] = finfo.toData();
@@ -235,7 +263,7 @@ void StuffItArchive::close() {
}
bool StuffItArchive::hasFile(const Common::Path &path) const {
- Common::String name = path.toString();
+ Common::String name = path.toString(':');
return _map.contains(name);
}
@@ -247,7 +275,7 @@ int StuffItArchive::listMembers(Common::ArchiveMemberList &list) const {
}
const Common::ArchiveMemberPtr StuffItArchive::getMember(const Common::Path &path) const {
- Common::String name = path.toString();
+ Common::String name = path.toString(':');
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
}
@@ -1046,10 +1074,10 @@ void StuffItArchive::decompress14(Common::SeekableReadStream *src, byte *dst, ui
#undef OUTPUT_VAL
#undef ALIGN_BITS
-Common::Archive *createStuffItArchive(const Common::String &fileName) {
+Common::Archive *createStuffItArchive(const Common::String &fileName, bool flattenTree) {
StuffItArchive *archive = new StuffItArchive();
- if (!archive->open(fileName)) {
+ if (!archive->open(fileName, flattenTree)) {
delete archive;
return nullptr;
}
@@ -1057,10 +1085,10 @@ Common::Archive *createStuffItArchive(const Common::String &fileName) {
return archive;
}
-Common::Archive *createStuffItArchive(Common::SeekableReadStream *stream) {
+Common::Archive *createStuffItArchive(Common::SeekableReadStream *stream, bool flattenTree) {
StuffItArchive *archive = new StuffItArchive();
- if (!archive->open(stream)) {
+ if (!archive->open(stream, flattenTree)) {
delete archive;
return nullptr;
}
diff --git a/common/compression/stuffit.h b/common/compression/stuffit.h
index 4350f4c69ba..3e56be491eb 100644
--- a/common/compression/stuffit.h
+++ b/common/compression/stuffit.h
@@ -52,8 +52,8 @@ class SeekableReadStream;
*
* May return 0 in case of a failure.
*/
-Archive *createStuffItArchive(const String &fileName);
-Archive *createStuffItArchive(SeekableReadStream *stream);
+Archive *createStuffItArchive(const String &fileName, bool flattenTree = false);
+Archive *createStuffItArchive(SeekableReadStream *stream, bool flattenTree = false);
/** @} */
diff --git a/engines/grim/grim.cpp b/engines/grim/grim.cpp
index 420f5e612ff..5a079197bc7 100644
--- a/engines/grim/grim.cpp
+++ b/engines/grim/grim.cpp
@@ -334,13 +334,13 @@ Common::Error GrimEngine::run() {
// Currently, this requires the data fork to be standalone
if (getGameType() == GType_MONKEY4) {
if (SearchMan.hasFile("Monkey Island 4 Installer")) {
- Common::Archive *archive = Common::createStuffItArchive("Monkey Island 4 Installer");
+ Common::Archive *archive = Common::createStuffItArchive("Monkey Island 4 Installer", true);
if (archive)
SearchMan.add("Monkey Island 4 Installer", archive, 0, true);
}
if (SearchMan.hasFile("EFMI Installer")) {
- Common::Archive *archive = Common::createStuffItArchive("EFMI Installer");
+ Common::Archive *archive = Common::createStuffItArchive("EFMI Installer", true);
if (archive)
SearchMan.add("EFMI Installer", archive, 0, true);
diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp
index c818e412a3f..3a789c57711 100644
--- a/engines/groovie/groovie.cpp
+++ b/engines/groovie/groovie.cpp
@@ -82,7 +82,7 @@ Common::Error GroovieEngine::run() {
if (_gameDescription->version == kGroovieT11H && getPlatform() == Common::kPlatformMacintosh) {
// Load the Mac installer with the lowest priority (in case the user has installed
// the game and has the MIDI folder present; faster to just load them)
- Common::Archive *archive = Common::createStuffItArchive("The 11th Hour Installer");
+ Common::Archive *archive = Common::createStuffItArchive("The 11th Hour Installer", true);
if (archive)
SearchMan.add("The 11th Hour Installer", archive);
diff --git a/engines/kyra/resource/resource_intern.cpp b/engines/kyra/resource/resource_intern.cpp
index 64a53ac553b..68102f4f2d8 100644
--- a/engines/kyra/resource/resource_intern.cpp
+++ b/engines/kyra/resource/resource_intern.cpp
@@ -1223,7 +1223,7 @@ Common::Archive *StuffItLoader::load(Resource *owner, const Common::String &file
Common::Archive *StuffItLoader::load(Resource *owner, Common::SeekableReadStream *stream, const Common::String& debugName) {
if (stream) {
- Common::Archive *archive = Common::createStuffItArchive(stream);
+ Common::Archive *archive = Common::createStuffItArchive(stream, true);
return archive;
}
diff --git a/engines/mtropolis/boot.cpp b/engines/mtropolis/boot.cpp
index 1e2c0c2d721..d20fcb42bd2 100644
--- a/engines/mtropolis/boot.cpp
+++ b/engines/mtropolis/boot.cpp
@@ -243,7 +243,7 @@ void ObsidianGameDataHandler::unpackMacRetailInstaller(Common::Array<Common::Sha
error("Obsidian Installer has no data fork");
// Not counted/persisted because the StuffIt archive owns the stream. It will also delete it if createStuffItArchive fails.
- _installerArchive.reset(Common::createStuffItArchive(installerDataForkStream));
+ _installerArchive.reset(Common::createStuffItArchive(installerDataForkStream, true));
installerDataForkStream = nullptr;
persistentResources.push_back(PersistentResource<Common::Archive>::wrap(_installerArchive));
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 15a27a8dd30..296832eb60b 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -152,7 +152,7 @@ Common::SeekableReadStream *PrivateEngine::loadAssets() {
else
file = Common::MacResManager::openFileOrDataFork(isDemo() ? "Private Eye Demo Installer" : "Private Eye Installer");
if (file) {
- Common::Archive *s = createStuffItArchive(file);
+ Common::Archive *s = createStuffItArchive(file, true);
Common::SeekableReadStream *file2 = nullptr;
if (s)
file2 = s->createReadStreamForMember(isDemo() ? "demogame.mac" : "game.mac");
Commit: e53d2ec59481c8ec95dc0157180bb08af594b6db
https://github.com/scummvm/scummvm/commit/e53d2ec59481c8ec95dc0157180bb08af594b6db
Author: elasota (ejlasota at gmail.com)
Date: 2023-06-19T08:45:32+03:00
Commit Message:
COMMON: Add "getPathSeparator" to Archive and return ":" for Mac archive formats
Changed paths:
common/archive.cpp
common/archive.h
common/compression/stuffit.cpp
common/compression/vise.cpp
diff --git a/common/archive.cpp b/common/archive.cpp
index 62b7e277b9e..c09a2aecccf 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -103,6 +103,10 @@ void Archive::dumpArchive(String destPath) {
free(data);
}
+char Archive::getPathSeparator() const {
+ return '/';
+}
+
SeekableReadStream *MemcachingCaseInsensitiveArchive::createReadStreamForMember(const Path &path) const {
String translated = translatePath(path);
bool isNew = false;
diff --git a/common/archive.h b/common/archive.h
index 462ac4ec279..8a31928958e 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -155,6 +155,11 @@ public:
* Dump all files from the archive to the given directory
*/
void dumpArchive(String destPath);
+
+ /**
+ * Returns the separator used by internal paths in the archive
+ */
+ virtual char getPathSeparator() const;
};
class MemcachingCaseInsensitiveArchive;
diff --git a/common/compression/stuffit.cpp b/common/compression/stuffit.cpp
index d6011b168e2..1e7797e2159 100644
--- a/common/compression/stuffit.cpp
+++ b/common/compression/stuffit.cpp
@@ -53,9 +53,8 @@ public:
int listMembers(Common::ArchiveMemberList &list) const override;
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
Common::SharedArchiveContents readContentsForPath(const Common::String& name) const override;
- Common::String translatePath(const Common::Path &path) const override {
- return path.toString(':');
- }
+ Common::String translatePath(const Common::Path &path) const override;
+ char getPathSeparator() const override;
private:
struct FileEntry {
@@ -74,6 +73,8 @@ private:
typedef Common::HashMap<Common::String, Common::MacFinderInfoData, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> MetadataMap;
MetadataMap _metadataMap;
+ bool _flattenTree;
+
// Decompression Functions
bool decompress13(Common::SeekableReadStream *src, byte *dst, uint32 uncompressedSize) const;
void decompress14(Common::SeekableReadStream *src, byte *dst, uint32 uncompressedSize) const;
@@ -83,7 +84,7 @@ private:
void readTree14(Common::BitStream8LSB *bits, SIT14Data *dat, uint16 codesize, uint16 *result) const;
};
-StuffItArchive::StuffItArchive() : Common::MemcachingCaseInsensitiveArchive() {
+StuffItArchive::StuffItArchive() : Common::MemcachingCaseInsensitiveArchive(), _flattenTree(false) {
_stream = nullptr;
}
@@ -108,6 +109,7 @@ bool StuffItArchive::open(Common::SeekableReadStream *stream, bool flattenTree)
close();
_stream = stream;
+ _flattenTree = flattenTree;
if (!_stream)
return false;
@@ -325,6 +327,14 @@ Common::SharedArchiveContents StuffItArchive::readContentsForPath(const Common::
return Common::SharedArchiveContents(uncompressedBlock, entry.uncompressedSize);
}
+Common::String StuffItArchive::translatePath(const Common::Path &path) const {
+ return _flattenTree ? path.getLastComponent().toString() : path.toString(':');
+}
+
+char StuffItArchive::getPathSeparator() const {
+ return ':';
+}
+
void StuffItArchive::update14(uint16 first, uint16 last, byte *code, uint16 *freq) const {
uint16 i, j;
diff --git a/common/compression/vise.cpp b/common/compression/vise.cpp
index c1ada443a78..660049b8e08 100644
--- a/common/compression/vise.cpp
+++ b/common/compression/vise.cpp
@@ -94,6 +94,7 @@ public:
int listMembers(Common::ArchiveMemberList &list) const override;
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
+ char getPathSeparator() const override;
private:
bool getFileDescIndex(const Common::Path &path, uint &outIndex, ArchiveMember::SubstreamType &outSubstreamType) const;
@@ -390,6 +391,10 @@ Common::SeekableReadStream *MacVISEArchive::createReadStreamForMember(const Comm
return archiveMember->createReadStream();
}
+char MacVISEArchive::getPathSeparator() const {
+ return ':';
+}
+
bool MacVISEArchive::getFileDescIndex(const Common::Path &path, uint &outIndex, ArchiveMember::SubstreamType &outSubstreamType) const {
Common::String convertedPath = path.toString(':');
ArchiveMember::SubstreamType substreamType = ArchiveMember::kSubstreamTypeData;
Commit: 907252ecbdc6e0db6d8ac39ad649fca548c0ac1a
https://github.com/scummvm/scummvm/commit/907252ecbdc6e0db6d8ac39ad649fca548c0ac1a
Author: elasota (ejlasota at gmail.com)
Date: 2023-06-19T08:45:32+03:00
Commit Message:
COMMON: Return correct path separator for InstallShieldV3
Changed paths:
common/compression/installshieldv3_archive.cpp
common/compression/installshieldv3_archive.h
diff --git a/common/compression/installshieldv3_archive.cpp b/common/compression/installshieldv3_archive.cpp
index 92cf3c7c416..e52228b4aa6 100644
--- a/common/compression/installshieldv3_archive.cpp
+++ b/common/compression/installshieldv3_archive.cpp
@@ -153,4 +153,8 @@ Common::SeekableReadStream *InstallShieldV3::createReadStreamForMember(const Com
return Common::decompressDCL(_stream, entry.compressedSize, entry.uncompressedSize);
}
+char InstallShieldV3::getPathSeparator() const {
+ return '\\';
+}
+
} // End of namespace Common
diff --git a/common/compression/installshieldv3_archive.h b/common/compression/installshieldv3_archive.h
index 1823df09b39..ee5ccc0e65a 100644
--- a/common/compression/installshieldv3_archive.h
+++ b/common/compression/installshieldv3_archive.h
@@ -46,6 +46,7 @@ public:
int listMembers(Common::ArchiveMemberList &list) const override;
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
+ char getPathSeparator() const override;
private:
struct FileEntry {
Commit: 654f7fd8d0dcdef4ff392372f2d6a56f0a3086bc
https://github.com/scummvm/scummvm/commit/654f7fd8d0dcdef4ff392372f2d6a56f0a3086bc
Author: elasota (ejlasota at gmail.com)
Date: 2023-06-19T08:45:32+03:00
Commit Message:
COMMON: Add comments on usage
Changed paths:
common/compression/stuffit.h
diff --git a/common/compression/stuffit.h b/common/compression/stuffit.h
index 3e56be491eb..fa234106e71 100644
--- a/common/compression/stuffit.h
+++ b/common/compression/stuffit.h
@@ -50,7 +50,10 @@ class SeekableReadStream;
* This factory method creates an Archive instance corresponding to the content
* of the StuffIt compressed file with the given name.
*
- * May return 0 in case of a failure.
+ * @param fileName The file name to load
+ * @param flattenTree If true, removes the directory prefixes from all file paths
+ *
+ * @return The StuffIt archive
*/
Archive *createStuffItArchive(const String &fileName, bool flattenTree = false);
Archive *createStuffItArchive(SeekableReadStream *stream, bool flattenTree = false);
More information about the Scummvm-git-logs
mailing list