Skip to content

Commit

Permalink
COMMON: Archive path refactoring, add getFileName and getPathInArchiv…
Browse files Browse the repository at this point in the history
…e that unambiguously return the filename or the full path
  • Loading branch information
elasota committed Jul 6, 2023
1 parent cd970d5 commit 92177ca
Show file tree
Hide file tree
Showing 46 changed files with 224 additions and 96 deletions.
5 changes: 2 additions & 3 deletions backends/platform/sdl/win32/win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,14 +455,13 @@ int Win32ResourceArchive::listMembers(Common::ArchiveMemberList &list) const {
int count = 0;

for (FilenameList::const_iterator i = _files.begin(); i != _files.end(); ++i, ++count)
list.push_back(Common::ArchiveMemberPtr(new Common::GenericArchiveMember(*i, this)));
list.push_back(Common::ArchiveMemberPtr(new Common::GenericArchiveMember(*i, *this)));

return count;
}

const Common::ArchiveMemberPtr Win32ResourceArchive::getMember(const Common::Path &path) const {
Common::String name = path.toString();
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(path, *this));
}

Common::SeekableReadStream *Win32ResourceArchive::createReadStreamForMember(const Common::Path &path) const {
Expand Down
25 changes: 20 additions & 5 deletions common/archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,28 @@

namespace Common {

GenericArchiveMember::GenericArchiveMember(const String &name, const Archive *parent)
: _parent(parent), _name(name) {
GenericArchiveMember::GenericArchiveMember(const String &pathStr, const Archive &parent)
: _parent(parent), _path(pathStr, parent.getPathSeparator()) {
}

GenericArchiveMember::GenericArchiveMember(const Path &path, const Archive &parent)
: _parent(parent), _path(path) {
}

String GenericArchiveMember::getName() const {
return _name;
return _path.toString(_parent.getPathSeparator());
}

Path GenericArchiveMember::getPathInArchive() const {
return _path;
}

String GenericArchiveMember::getFileName() const {
return _path.getLastComponent().toString(_parent.getPathSeparator());
}

SeekableReadStream *GenericArchiveMember::createReadStream() const {
return _parent->createReadStreamForMember(_name);
return _parent.createReadStreamForMember(_path);
}


Expand All @@ -49,7 +61,10 @@ int Archive::listMatchingMembers(ArchiveMemberList &list, const Path &pattern, b

String patternString = pattern.toString();
int matches = 0;
const char *wildcardExclusions = matchPathComponents ? NULL : "/";

char pathSepString[2] = {getPathSeparator(), '\0'};

const char *wildcardExclusions = matchPathComponents ? NULL : pathSepString;

ArchiveMemberList::const_iterator it = allNames.begin();
for (; it != allNames.end(); ++it) {
Expand Down
26 changes: 20 additions & 6 deletions common/archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,15 @@ class ArchiveMember {
public:
virtual ~ArchiveMember() { }
virtual SeekableReadStream *createReadStream() const = 0; /*!< Create a read stream. */
virtual String getName() const = 0; /*!< Get the name of the archive member. */

/**
* @deprecated Get the name of the archive member. This may be a file name or a full path depending on archive type.
* DEPRECATED: Use getFileName or getPathInArchive instead, which always returns one or the other.
*/
virtual String getName() const = 0;

virtual Path getPathInArchive() const = 0; /*!< Get the full path of the archive member relative to the containing archive root. */
virtual String getFileName() const = 0; /*!< Get the file name of the archive member relative to its containing directory within the archive. */
virtual U32String getDisplayName() const { return getName(); } /*!< Get the display name of the archive member. */
};

Expand Down Expand Up @@ -86,12 +94,18 @@ class Archive;
* is destroyed.
*/
class GenericArchiveMember : public ArchiveMember {
const Archive *_parent;
const String _name;
public:
GenericArchiveMember(const String &name, const Archive *parent); /*!< Create a generic archive member that belongs to the @p parent archive. */
String getName() const; /*!< Get the name of a generic archive member. */
SeekableReadStream *createReadStream() const; /*!< Create a read stream. */
GenericArchiveMember(const Common::String &pathStr, const Archive &parent); /*!< Create a generic archive member that belongs to the @p parent archive. */
GenericArchiveMember(const Common::Path &path, const Archive &parent); /*!< Create a generic archive member that belongs to the @p parent archive. */

String getName() const override; /*!< Get the name of a generic archive member. */
Path getPathInArchive() const override; /*!< Get the full path of the archive member relative to the containing archive root. */
String getFileName() const override; /*!< Get the file name of the archive member relative to its containing directory within the archive. */
SeekableReadStream *createReadStream() const override; /*!< Create a read stream. */

private:
const Archive &_parent;
const Common::Path _path;
};


Expand Down
4 changes: 2 additions & 2 deletions common/compression/clickteam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ int ClickteamInstaller::listMembers(ArchiveMemberList &list) const {
for (Common::HashMap<Common::String, ClickteamFileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>::const_iterator i = _files.begin(), end = _files.end();
i != end; ++i) {
if (!i->_value._isReferenceMissing) {
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(i->_key, this)));
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(i->_key, *this)));
++members;
}
}
Expand All @@ -491,7 +491,7 @@ const ArchiveMemberPtr ClickteamInstaller::getMember(const Path &path) const {
if (el._isReferenceMissing)
return nullptr;

return Common::SharedPtr<Common::ArchiveMember>(new GenericArchiveMember(el._fileName, this));
return Common::SharedPtr<Common::ArchiveMember>(new GenericArchiveMember(el._fileName, *this));
}

Common::SharedArchiveContents ClickteamInstaller::readContentsForPath(const Common::String& translated) const {
Expand Down
2 changes: 2 additions & 0 deletions common/compression/gentee_installer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,8 @@ class ArchiveItem : public Common::ArchiveMember {

Common::SeekableReadStream *createReadStream() const override;
Common::String getName() const override;
Common::Path getPathInArchive() const override { return getName(); }
Common::String getFileName() const override { return getName(); }

const Common::String &getPath() const;

Expand Down
3 changes: 1 addition & 2 deletions common/compression/installshield_cab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,7 @@ int InstallShieldCabinet::listMembers(ArchiveMemberList &list) const {
}

const ArchiveMemberPtr InstallShieldCabinet::getMember(const Path &path) const {
String name = path.toString();
return ArchiveMemberPtr(new GenericArchiveMember(name, this));
return ArchiveMemberPtr(new GenericArchiveMember(path, *this));
}

SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(const Path &path) const {
Expand Down
2 changes: 1 addition & 1 deletion common/compression/installshieldv3_archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ int InstallShieldV3::listMembers(Common::ArchiveMemberList &list) const {

const Common::ArchiveMemberPtr InstallShieldV3::getMember(const Common::Path &path) const {
Common::String name = path.toString();
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, *this));
}

Common::SeekableReadStream *InstallShieldV3::createReadStreamForMember(const Common::Path &path) const {
Expand Down
3 changes: 1 addition & 2 deletions common/compression/stuffit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,7 @@ int StuffItArchive::listMembers(Common::ArchiveMemberList &list) const {
}

const Common::ArchiveMemberPtr StuffItArchive::getMember(const Common::Path &path) const {
Common::String name = path.toString(':');
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(path, *this));
}

Common::SharedArchiveContents StuffItArchive::readContentsForPath(const Common::String& name) const {
Expand Down
4 changes: 2 additions & 2 deletions common/compression/unarj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ int ArjArchive::listMembers(ArchiveMemberList &list) const {

ArjHeadersMap::const_iterator it = _headers.begin();
for ( ; it != _headers.end(); ++it) {
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(it->_value[0]._header->filename, this)));
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(Common::String(it->_value[0]._header->filename), *this)));
matches++;
}

Expand All @@ -787,7 +787,7 @@ const ArchiveMemberPtr ArjArchive::getMember(const Path &path) const {
if (!hasFile(name))
return ArchiveMemberPtr();

return ArchiveMemberPtr(new GenericArchiveMember(name, this));
return ArchiveMemberPtr(new GenericArchiveMember(name, *this));
}

Common::SharedArchiveContents ArjArchive::readContentsForPath(const Common::String& name) const {
Expand Down
4 changes: 2 additions & 2 deletions common/compression/unzip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ int ZipArchive::listMembers(ArchiveMemberList &list) const {
const unz_s *const archive = (const unz_s *)_zipFile;
for (ZipHash::const_iterator i = archive->_hash.begin(), end = archive->_hash.end();
i != end; ++i) {
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(i->_key, this)));
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(i->_key, *this)));
++members;
}

Expand All @@ -1037,7 +1037,7 @@ const ArchiveMemberPtr ZipArchive::getMember(const Path &path) const {
if (!hasFile(name))
return ArchiveMemberPtr();

return ArchiveMemberPtr(new GenericArchiveMember(name, this));
return ArchiveMemberPtr(new GenericArchiveMember(path, *this));
}

Common::SharedArchiveContents ZipArchive::readContentsForPath(const Common::String& name) const {
Expand Down
37 changes: 27 additions & 10 deletions common/compression/vise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ class MacVISEArchive : public Common::Archive {
uint16 containingDirectory;

Common::String name;
Common::String fullPath;
Common::Path fullPath;
};

struct DirectoryDesc {
uint16 containingDirectory;

Common::String name;
Common::String fullPath;
Common::Path fullPath;
};

class ArchiveMember : public Common::ArchiveMember {
Expand All @@ -76,6 +76,8 @@ class MacVISEArchive : public Common::Archive {

Common::SeekableReadStream *createReadStream() const override;
Common::String getName() const override;
Common::Path getPathInArchive() const override;
Common::String getFileName() const override;

private:
Common::SeekableReadStream *_archiveStream;
Expand Down Expand Up @@ -199,14 +201,27 @@ Common::SeekableReadStream *MacVISEArchive::ArchiveMember::createReadStream() co
}

Common::String MacVISEArchive::ArchiveMember::getName() const {
return getPathInArchive().getLastComponent().toString(':');
}

Common::Path MacVISEArchive::ArchiveMember::getPathInArchive() const {
if (_substreamType == kSubstreamTypeFinderInfo)
return _fileDesc->fullPath + ".finf";
return _fileDesc->fullPath.append(".finf", ':');
else if (_substreamType == kSubstreamTypeResource)
return _fileDesc->fullPath + ".rsrc";
return _fileDesc->fullPath.append(".rsrc", ':');
else
return _fileDesc->fullPath;
}

Common::String MacVISEArchive::ArchiveMember::getFileName() const {
if (_substreamType == kSubstreamTypeFinderInfo)
return _fileDesc->name + ".finf";
else if (_substreamType == kSubstreamTypeResource)
return _fileDesc->name + ".rsrc";
else
return _fileDesc->name;
}

MacVISEArchive::FileDesc::FileDesc() : type{0, 0, 0, 0}, creator{0, 0, 0, 0}, compressedDataSize(0), uncompressedDataSize(0), compressedResSize(0), uncompressedResSize(0), positionInArchive(0) {
}

Expand Down Expand Up @@ -320,7 +335,7 @@ bool MacVISEArchive::loadCatalog() {
if (dirDesc.containingDirectory > _directoryDescs.size())
error("VISE 3 containing directory index was invalid");

dirDesc.fullPath = _directoryDescs[dirDesc.containingDirectory - 1].fullPath + ":" + dirDesc.name;
dirDesc.fullPath = _directoryDescs[dirDesc.containingDirectory - 1].fullPath.appendComponent(dirDesc.name);
}
}

Expand All @@ -331,17 +346,16 @@ bool MacVISEArchive::loadCatalog() {
if (fileDesc.containingDirectory > _directoryDescs.size())
error("VISE 3 containing directory index was invalid");

fileDesc.fullPath = _directoryDescs[fileDesc.containingDirectory - 1].fullPath + ":" + fileDesc.name;
fileDesc.fullPath = _directoryDescs[fileDesc.containingDirectory - 1].fullPath.appendComponent(fileDesc.name);
}
}

return true;
}

const MacVISEArchive::FileDesc *MacVISEArchive::getFileDesc(const Common::Path &path) const {
Common::String convertedPath = path.toString(':');
for (const FileDesc &desc : _fileDescs) {
if (desc.fullPath == convertedPath)
if (desc.fullPath == path)
return &desc;
}

Expand Down Expand Up @@ -396,7 +410,8 @@ char MacVISEArchive::getPathSeparator() const {
}

bool MacVISEArchive::getFileDescIndex(const Common::Path &path, uint &outIndex, ArchiveMember::SubstreamType &outSubstreamType) const {
Common::String convertedPath = path.toString(':');
Common::String convertedPath = path.toString(getPathSeparator());

ArchiveMember::SubstreamType substreamType = ArchiveMember::kSubstreamTypeData;
if (convertedPath.hasSuffix(".rsrc")) {
substreamType = ArchiveMember::kSubstreamTypeResource;
Expand All @@ -406,10 +421,12 @@ bool MacVISEArchive::getFileDescIndex(const Common::Path &path, uint &outIndex,
convertedPath = convertedPath.substr(0, convertedPath.size() - 5);
}

Common::Path filePath(convertedPath, getPathSeparator());

for (uint descIndex = 0; descIndex < _fileDescs.size(); descIndex++) {
const FileDesc &desc = _fileDescs[descIndex];

if (desc.fullPath == convertedPath) {
if (desc.fullPath == filePath) {
if (substreamType == ArchiveMember::SubstreamType::kSubstreamTypeData && desc.uncompressedDataSize == 0)
return false;
if (substreamType == ArchiveMember::SubstreamType::kSubstreamTypeResource && desc.uncompressedResSize == 0)
Expand Down
8 changes: 8 additions & 0 deletions common/formats/prodos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ Common::String ProDOSFile::getName() const {
return Common::String(_name);
}

Common::String ProDOSFile::getFileName() const {
return Common::String(_name);
}

Common::Path ProDOSFile::getPathInArchive() const {
return Common::Path(_name);
}

/* This method is used to get a single block of data from the disk,
* but is not strictly 512 bytes. This is so that it can get only what
* it needs when in the final block. It then adds it into the allocated
Expand Down
2 changes: 2 additions & 0 deletions common/formats/prodos.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class ProDOSFile : public Common::ArchiveMember {

// -- These are the Common::ArchiveMember related functions --
Common::String getName() const override; // Returns _name
Common::Path getPathInArchive() const override; // Returns _name
Common::String getFileName() const override; // Returns _name
Common::SeekableReadStream *createReadStream() const override; // This is what the archive needs to create a file
void getDataBlock(byte *memOffset, int offset, int size) const; // Gets data up to the size of a single data block (512 bytes)
int parseIndexBlock(byte *memOffset, int blockNum, int cSize) const; // Uses getDataBlock() on every pointer in the index file, adding them to byte * memory block
Expand Down

0 comments on commit 92177ca

Please sign in to comment.