Răsfoiți Sursa

Enables pattern searches to enter zipped sub-directories.

OTHGMars 4 ani în urmă
părinte
comite
0484956a1f

+ 79 - 0
Engine/source/core/util/zip/zipVolume.cpp

@@ -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)
    {

+ 7 - 0
Engine/source/core/util/zip/zipVolume.h

@@ -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; }

+ 1 - 1
Engine/source/core/volume.cpp

@@ -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();
    }

+ 1 - 0
Engine/source/core/volume.h

@@ -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;