Skip to content

Commit

Permalink
#5108: Hook the IArchiveFileInfoProvider reference into the traversal…
Browse files Browse the repository at this point in the history
… routines.

The IArchive implementations now implement IArchiveFileInfoProvider too.
  • Loading branch information
codereader committed Nov 20, 2020
1 parent 96e15e3 commit 6148236
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 22 deletions.
2 changes: 1 addition & 1 deletion include/iarchive.h
Expand Up @@ -91,7 +91,7 @@ class IArchive
virtual ~Visitor() {}

// Invoked for each file in an Archive
virtual void visitFile(const std::string& name) = 0;
virtual void visitFile(const std::string& name, IArchiveFileInfoProvider& infoProvider) = 0;

// Invoked for each directory in an Archive. Return true to skip the directory.
virtual bool visitDirectory(const std::string& name, std::size_t depth) = 0;
Expand Down
2 changes: 1 addition & 1 deletion libs/os/file.h
Expand Up @@ -99,7 +99,7 @@ inline bool fileOrDirExists(const fs::path& path)
}
}

// Returns the file size in bytes, or static_cast<uintmax_t>(-1)
// Returns the file size in bytes, or static_cast<std::size_t>(-1)
inline std::size_t getFileSize(const std::string& path)
{
try
Expand Down
3 changes: 1 addition & 2 deletions libs/wxutil/fsview/Populator.cpp
Expand Up @@ -77,8 +77,7 @@ void Populator::visitFile(const vfs::FileInfo& fileInfo)
if (!isFolder)
{
// Get the file size if possible
auto file = GlobalFileSystem().openFile(_basePath + path);
row[_columns.size] = os::getFormattedFileSize(file ? file->size() : -1);
row[_columns.size] = os::getFormattedFileSize(fileInfo.getSize());
}
});
}
Expand Down
14 changes: 13 additions & 1 deletion radiantcore/vfs/DirectoryArchive.cpp
Expand Up @@ -87,7 +87,7 @@ void DirectoryArchive::traverse(Visitor& visitor, const std::string& root)
else
{
// File
visitor.visitFile(candidateStr.substr(rootLen));
visitor.visitFile(candidateStr.substr(rootLen), *this);
}
}
catch (const std::system_error& ex)
Expand All @@ -98,3 +98,15 @@ void DirectoryArchive::traverse(Visitor& visitor, const std::string& root)
}
}
}

std::size_t DirectoryArchive::getFileSize(const std::string& relativePath)
{
UnixPath path(_root);
return os::getFileSize(std::string(path) + relativePath);
}

bool DirectoryArchive::getIsPhysical(const std::string& relativePath)
{
// this whole class represents a physical directory, we don't even check
return true;
}
17 changes: 9 additions & 8 deletions radiantcore/vfs/DirectoryArchive.h
Expand Up @@ -9,8 +9,9 @@
* A real folder is treated like any other "archive" and gets
* added to the list of PK4 archives, using this class.
*/
class DirectoryArchive :
public IArchive
class DirectoryArchive final :
public IArchive,
public IArchiveFileInfoProvider
{
std::string _root;

Expand All @@ -23,12 +24,12 @@ class DirectoryArchive :
// Pass the root path to the constructor
DirectoryArchive(const std::string& root);

virtual ArchiveFilePtr openFile(const std::string& name) override;
ArchiveFilePtr openFile(const std::string& name) override;
ArchiveTextFilePtr openTextFile(const std::string& name) override;
bool containsFile(const std::string& name) override;
void traverse(Visitor& visitor, const std::string& root) override;

virtual ArchiveTextFilePtr openTextFile(const std::string& name) override;

virtual bool containsFile(const std::string& name) override;

virtual void traverse(Visitor& visitor, const std::string& root) override;
std::size_t getFileSize(const std::string& relativePath) override;
bool getIsPhysical(const std::string& relativePath) override;
};
typedef std::shared_ptr<DirectoryArchive> DirectoryArchivePtr;
4 changes: 2 additions & 2 deletions radiantcore/vfs/FileVisitor.h
Expand Up @@ -64,7 +64,7 @@ class FileVisitor :
}

// Archive::Visitor interface
void visitFile(const std::string& name) override
void visitFile(const std::string& name, IArchiveFileInfoProvider& infoProvider) override
{
#ifdef OS_CASE_INSENSITIVE
// The name should start with the directory, "def/" for instance, case-insensitively.
Expand Down Expand Up @@ -112,7 +112,7 @@ class FileVisitor :
// Suitable file, call the callback and add to visited file set
vfs::Visibility vis = _assetsList ? _assetsList->getVisibility(subname)
: Visibility::NORMAL;
_visitorFunc(vfs::FileInfo{ _directory, subname, vis });
_visitorFunc(vfs::FileInfo(_directory, subname, vis, infoProvider));

_visitedFiles.insert(subname);
}
Expand Down
4 changes: 2 additions & 2 deletions radiantcore/vfs/GenericFileSystem.h
Expand Up @@ -164,7 +164,7 @@ class GenericFileSystem
/// Traverses the entire tree if \p root is "".
/// Calls \p visitor.file() with the path to each file relative to the filesystem root.
/// Calls \p visitor.directory() with the path to each directory relative to the filesystem root.
void traverse(IArchive::Visitor& visitor, const std::string& root)
void traverse(IArchive::Visitor& visitor, const std::string& root, IArchiveFileInfoProvider& infoProvider)
{
unsigned int start_depth = getPathDepth(root.c_str());
unsigned int skip_depth = 0;
Expand All @@ -180,7 +180,7 @@ class GenericFileSystem
{
if (!i->second.isDirectory())
{
visitor.visitFile(i->first.string());
visitor.visitFile(i->first.string(), infoProvider);
}
else if (visitor.visitDirectory(i->first.string(), i->first.depth() - start_depth))
{
Expand Down
14 changes: 13 additions & 1 deletion radiantcore/vfs/ZipArchive.cpp
Expand Up @@ -143,7 +143,19 @@ bool ZipArchive::containsFile(const std::string& name)

void ZipArchive::traverse(Visitor& visitor, const std::string& root)
{
_filesystem.traverse(visitor, root);
_filesystem.traverse(visitor, root, *this);
}

std::size_t ZipArchive::getFileSize(const std::string& relativePath)
{
auto i = _filesystem.find(relativePath);
return i != _filesystem.end() ? i->second.getRecord()->file_size : 0;
}

bool ZipArchive::getIsPhysical(const std::string& relativePath)
{
// this archive is a ZIP file, so no physicality here
return false;
}

void ZipArchive::readZipRecord()
Expand Down
12 changes: 8 additions & 4 deletions radiantcore/vfs/ZipArchive.h
Expand Up @@ -17,8 +17,9 @@ namespace archive
*
* Archives are owned and instantiated by the GlobalFileSystem instance.
*/
class ZipArchive :
public IArchive
class ZipArchive final :
public IArchive,
public IArchiveFileInfoProvider
{
private:
class ZipRecord
Expand Down Expand Up @@ -59,11 +60,14 @@ class ZipArchive :
virtual ~ZipArchive();

// Archive implementation
virtual ArchiveFilePtr openFile(const std::string& name) override;
virtual ArchiveTextFilePtr openTextFile(const std::string& name) override;
ArchiveFilePtr openFile(const std::string& name) override;
ArchiveTextFilePtr openTextFile(const std::string& name) override;
bool containsFile(const std::string& name) override;
void traverse(Visitor& visitor, const std::string& root) override;

std::size_t getFileSize(const std::string& relativePath) override;
bool getIsPhysical(const std::string& relativePath) override;

private:
void readZipRecord();
void loadZipFile();
Expand Down

0 comments on commit 6148236

Please sign in to comment.