Skip to content

Commit

Permalink
#5108: Move Archive interface to iarchive.h to make it public. Add Vi…
Browse files Browse the repository at this point in the history
…rtualFileSystem::openArchiveInAbsolutePath method to load an independent PAK file for inspection.
  • Loading branch information
codereader committed Nov 17, 2020
1 parent 6df3f91 commit cb121ff
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 69 deletions.
46 changes: 46 additions & 0 deletions include/iarchive.h
Expand Up @@ -57,3 +57,49 @@ class ArchiveTextFile :
};
typedef std::shared_ptr<ArchiveTextFile> ArchiveTextFilePtr;

/**
* Representation of an archive in the virtual filesystem.
* This might be a PK4/ZIP file or a regular mod directory.
*
* \ingroup vfs
*/
class IArchive
{
public:
typedef std::shared_ptr<IArchive> Ptr;

virtual ~IArchive() {}

class Visitor
{
public:
virtual ~Visitor() {}

// Invoked for each file in an Archive
virtual void visitFile(const std::string& name) = 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;
};

/// \brief Returns a new object associated with the file identified by \p name, or 0 if the file cannot be opened.
/// Name comparisons are case-insensitive.
virtual ArchiveFilePtr openFile(const std::string& name) = 0;

/// \brief Returns a new object associated with the file identified by \p name, or 0 if the file cannot be opened.
/// Name comparisons are case-insensitive.
virtual ArchiveTextFilePtr openTextFile(const std::string& name) = 0;

/// Returns true if the file identified by \p name can be opened.
/// Name comparisons are case-insensitive.
virtual bool containsFile(const std::string& name) = 0;

/// \brief Performs a depth-first traversal of the archive tree starting at \p root.
/// Traverses the entire tree if \p root is "".
/// When a file is encountered, calls \c visitor.file passing the file name.
/// When a directory is encountered, calls \c visitor.directory passing the directory name.
/// Skips the directory if \c visitor.directory returned true.
/// Root comparisons are case-insensitive.
/// Names are mixed-case.
virtual void traverse(Visitor& visitor, const std::string& root) = 0;
};
11 changes: 6 additions & 5 deletions include/ifilesystem.h
Expand Up @@ -14,11 +14,7 @@
#include <algorithm>

#include "imodule.h"

class ArchiveFile;
typedef std::shared_ptr<ArchiveFile> ArchiveFilePtr;
class ArchiveTextFile;
typedef std::shared_ptr<ArchiveTextFile> ArchiveTextFilePtr;
#include "iarchive.h"

namespace vfs
{
Expand Down Expand Up @@ -171,6 +167,11 @@ class VirtualFileSystem :
/// This is a variant of openTextFile taking an absolute path as argument.
virtual ArchiveTextFilePtr openTextFileInAbsolutePath(const std::string& filename) = 0;

// Opens an independent archive located in the given physical path.
// (This archive can be located somewhere outside the current VFS hierarchy.)
// Loading this archive won't have any effect on the VFS setup, it is opened stand-alone.
virtual IArchive::Ptr openArchiveInAbsolutePath(const std::string& pathToArchive) = 0;

/// \brief Calls the visitor function for each file under \p basedir matching \p extension.
/// Use "*" as \p extension to match all file extensions.
virtual void forEachFile(const std::string& basedir,
Expand Down
51 changes: 0 additions & 51 deletions radiantcore/vfs/Archive.h

This file was deleted.

4 changes: 2 additions & 2 deletions radiantcore/vfs/DirectoryArchive.h
@@ -1,6 +1,6 @@
#pragma once

#include "Archive.h"
#include "iarchive.h"

/**
* greebo: This wraps around a certain path in the "real"
Expand All @@ -10,7 +10,7 @@
* added to the list of PK4 archives, using this class.
*/
class DirectoryArchive :
public Archive
public IArchive
{
std::string _root;

Expand Down
17 changes: 15 additions & 2 deletions radiantcore/vfs/Doom3FileSystem.cpp
Expand Up @@ -30,6 +30,7 @@
#include "string/encoding.h"
#include "os/path.h"
#include "os/dir.h"
#include "os/file.h"

#include "string/split.h"
#include "debugging/ScopedDebugTimer.h"
Expand Down Expand Up @@ -120,13 +121,14 @@ class AssetsList
};

/*
* Archive::Visitor class used in GlobalFileSystem().foreachFile().
* IArchive::Visitor class used in GlobalFileSystem().foreachFile().
* It's filtering out the files matching the defined extension only.
* The directory part is cut off the filename.
* On top of that, this class maintains a list of visited files to avoid
* hitting the same file twice (it might be present in more than one Archive).
*/
class FileVisitor: public Archive::Visitor
class FileVisitor :
public IArchive::Visitor
{
// Maximum traversal depth
std::size_t _maxDepth;
Expand Down Expand Up @@ -446,6 +448,17 @@ ArchiveTextFilePtr Doom3FileSystem::openTextFileInAbsolutePath(const std::string
return ArchiveTextFilePtr();
}

IArchive::Ptr Doom3FileSystem::openArchiveInAbsolutePath(const std::string& pathToArchive)
{
if (!os::fileIsReadable(pathToArchive))
{
rWarning() << "Requested file is not readable: " << pathToArchive << std::endl;
return IArchive::Ptr();
}

return std::make_shared<archive::ZipArchive>(pathToArchive);
}

void Doom3FileSystem::forEachFile(const std::string& basedir,
const std::string& extension,
const VisitorFunc& visitorFunc,
Expand Down
5 changes: 3 additions & 2 deletions radiantcore/vfs/Doom3FileSystem.h
@@ -1,6 +1,6 @@
#pragma once

#include "Archive.h"
#include "iarchive.h"
#include "ifilesystem.h"

namespace vfs
Expand All @@ -20,7 +20,7 @@ class Doom3FileSystem :
struct ArchiveDescriptor
{
std::string name;
ArchivePtr archive;
IArchive::Ptr archive;
bool is_pakfile;
};

Expand All @@ -42,6 +42,7 @@ class Doom3FileSystem :

ArchiveFilePtr openFileInAbsolutePath(const std::string& filename) override;
ArchiveTextFilePtr openTextFileInAbsolutePath(const std::string& filename) override;
IArchive::Ptr openArchiveInAbsolutePath(const std::string& pathToArchive) override;

// Call the specified callback function for each file matching extension
// inside basedir.
Expand Down
4 changes: 2 additions & 2 deletions radiantcore/vfs/GenericFileSystem.h
@@ -1,6 +1,6 @@
#pragma once

#include "Archive.h"
#include "iarchive.h"
#include "string/string.h"
#include "os/path.h"

Expand Down 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(Archive::Visitor& visitor, const std::string& root)
void traverse(IArchive::Visitor& visitor, const std::string& root)
{
unsigned int start_depth = getPathDepth(root.c_str());
unsigned int skip_depth = 0;
Expand Down
2 changes: 1 addition & 1 deletion radiantcore/vfs/ZipArchive.h
Expand Up @@ -18,7 +18,7 @@ namespace archive
* Archives are owned and instantiated by the GlobalFileSystem instance.
*/
class ZipArchive :
public Archive
public IArchive
{
private:
class ZipRecord
Expand Down
1 change: 0 additions & 1 deletion tools/msvc/DarkRadiantCore.vcxproj
Expand Up @@ -1016,7 +1016,6 @@
<ClInclude Include="..\..\radiantcore\undo\Stack.h" />
<ClInclude Include="..\..\radiantcore\undo\StackFiller.h" />
<ClInclude Include="..\..\radiantcore\undo\UndoSystem.h" />
<ClInclude Include="..\..\radiantcore\vfs\Archive.h" />
<ClInclude Include="..\..\radiantcore\vfs\DeflatedArchiveFile.h" />
<ClInclude Include="..\..\radiantcore\vfs\DeflatedArchiveTextFile.h" />
<ClInclude Include="..\..\radiantcore\vfs\DeflatedInputStream.h" />
Expand Down
3 changes: 0 additions & 3 deletions tools/msvc/DarkRadiantCore.vcxproj.filters
Expand Up @@ -1047,9 +1047,6 @@
<ClInclude Include="..\..\radiantcore\xmlregistry\XMLRegistry.h">
<Filter>src\xmlregistry</Filter>
</ClInclude>
<ClInclude Include="..\..\radiantcore\vfs\Archive.h">
<Filter>src\vfs</Filter>
</ClInclude>
<ClInclude Include="..\..\radiantcore\vfs\DeflatedArchiveFile.h">
<Filter>src\vfs</Filter>
</ClInclude>
Expand Down

0 comments on commit cb121ff

Please sign in to comment.