Enables pattern searches to enter zipped sub-directories.

This commit is contained in:
OTHGMars 2021-01-11 04:53:38 -05:00
parent 46b0aee637
commit 0484956a1f
4 changed files with 88 additions and 1 deletions

View file

@ -357,6 +357,10 @@ ZipFileSystem::ZipFileSystem(String& zipFilename, bool zipNameIsDir /* = false *
if(mZipNameIsDir)
{
Path path(zipFilename);
#ifdef TORQUE_DISABLE_FIND_ROOT_WITHIN_ZIP
if (path.getFileName().equal(path.getRoot()))
mZipNameIsDir = false;
#endif
mFakeRoot = Path::Join(path.getPath(), '/', path.getFileName());
}
@ -397,6 +401,81 @@ FileNodeRef ZipFileSystem::resolve(const Path& path)
if(name.isEmpty() && mZipNameIsDir)
return new ZipFakeRootNode(mZipArchive, path, mFakeRoot);
#ifdef TORQUE_LOWER_ZIPCASE
name = String::ToLower(name);
#endif
if(mZipNameIsDir)
{
// Remove the fake root from the name so things can be found
if(name.find(mFakeRoot) == 0)
name = name.substr(mFakeRoot.length());
#ifdef TORQUE_DISABLE_FIND_ROOT_WITHIN_ZIP
else
// If a zip file's name isn't the root of the path we're looking for
// then do not continue. Otherwise, we'll continue to look for the
// path's root within the zip file itself. i.e. we're looking for the
// path "scripts/test.cs". If the zip file itself isn't called scripts.zip
// then we won't look within the archive for a "scripts" directory.
return NULL;
#endif
if (name.find("/") == 0)
name = name.substr(1, name.length() - 1);
}
// first check to see if input path is a directory
// check for request of root directory
if (name.isEmpty())
{
ZipDirectoryNode* zdn = new ZipDirectoryNode(mZipArchive, path, mZipArchive->getRoot());
return zdn;
}
ZipArchive::ZipEntry* ze = mZipArchive->findZipEntry(name);
if (ze == NULL)
return NULL;
if (ze->mIsDirectory)
{
ZipDirectoryNode* zdn = new ZipDirectoryNode(mZipArchive, path, ze);
return zdn;
}
// pass in the zip entry so that openFile() doesn't need to look it up again.
Stream* stream = mZipArchive->openFile(name, ze, ZipArchive::Read);
if (stream == NULL)
return NULL;
ZipFileNode* zfn = new ZipFileNode(mZipArchive, name, stream, ze);
return zfn;
}
FileNodeRef ZipFileSystem::resolveLoose(const Path& path)
{
if (!mInitted)
_init();
if (mZipArchive.isNull())
return NULL;
// eat leading "/"
String name = path.getFullPathWithoutRoot();
if (name.find("/") == 0)
name = name.substr(1, name.length() - 1);
if(name.isEmpty() && mZipNameIsDir)
return new ZipFakeRootNode(mZipArchive, path, mFakeRoot);
#ifdef TORQUE_LOWER_ZIPCASE
name = String::ToLower(name);
#endif
if ((mFakeRoot.find(name) == 0) && (mFakeRoot.length() > name.length()))
{ // This file system is mounted as a sub-directory of the path being searched.
String tmpRoot = mFakeRoot.substr(name.length());
return new ZipFakeRootNode(mZipArchive, path, tmpRoot);
}
if(mZipNameIsDir)
{

View file

@ -40,8 +40,15 @@ public:
String getTypeStr() const { return "Zip"; }
// Strict resolve function will reteurn a node if it is mounted *AS* the requested path.
FileNodeRef resolve(const Path& path);
// Loose resolve function will return a node if it is mounted as or under the requested path.
// This is needed so mounted subdirectories will be included in recursive FindByPatern searches.
// i.e. If data/ui.zip is mounted as data/ui, a search for data/*.module will only include files
// under data/ui if the loose resolve function is used.
FileNodeRef resolveLoose(const Path& path);
// these are unsupported, ZipFileSystem is currently read only access
FileNodeRef create(const Path& path,FileNode::Mode) { return 0; }
bool remove(const Path& path) { return 0; }

View file

@ -730,7 +730,7 @@ S32 MountSystem::findByPattern( const Path &inBasePath, const String &inFilePatt
else
{
// use specified filesystem to open directory
FileNodeRef fNode = mFindByPatternOverrideFS->resolve(inBasePath);
FileNodeRef fNode = mFindByPatternOverrideFS->resolveLoose(inBasePath);
if (fNode && (dir = dynamic_cast<Directory*>(fNode.getPointer())) != NULL)
dir->open();
}

View file

@ -302,6 +302,7 @@ public:
virtual String getTypeStr() const = 0; ///< Used for describing the file system type
virtual FileNodeRef resolve(const Path& path) = 0;
virtual FileNodeRef resolveLoose(const Path& path) { return resolve(path); }
virtual FileNodeRef create(const Path& path,FileNode::Mode) = 0;
virtual bool remove(const Path& path) = 0;
virtual bool rename(const Path& a,const Path& b) = 0;