summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2017-04-24 03:35:02 +0300
committerAndrei Karas <akaras@inbox.ru>2017-04-24 04:35:35 +0300
commit0835e09ee3a6c83ffa01454f2c05597e6195b07d (patch)
treeb3b79b7a8f58f2ff18ec66b17d1c39ddad085e11
parent55458f743c3ff7e42288bc08033481d8464dca62 (diff)
downloadmv-0835e09ee3a6c83ffa01454f2c05597e6195b07d.tar.gz
mv-0835e09ee3a6c83ffa01454f2c05597e6195b07d.tar.bz2
mv-0835e09ee3a6c83ffa01454f2c05597e6195b07d.tar.xz
mv-0835e09ee3a6c83ffa01454f2c05597e6195b07d.zip
Improve VirtFs::getFiles.
-rw-r--r--src/fs/virtfs/virtfs.cpp22
-rw-r--r--src/fs/virtfs/virtfs.h7
-rw-r--r--src/fs/virtfs/virtfs1_unittest.cc73
-rw-r--r--src/fs/virtfs/virtfsdir.cpp51
-rw-r--r--src/fs/virtfs/virtfsdir.h3
-rw-r--r--src/fs/virtfs/virtfsfuncs.h4
-rw-r--r--src/fs/virtfs/virtfstools.cpp12
-rw-r--r--src/fs/virtfs/virtfstools.h2
-rw-r--r--src/fs/virtfs/virtfszip.cpp94
-rw-r--r--src/fs/virtfs/virtfszip.h3
10 files changed, 254 insertions, 17 deletions
diff --git a/src/fs/virtfs/virtfs.cpp b/src/fs/virtfs/virtfs.cpp
index d9423f66e..e61069301 100644
--- a/src/fs/virtfs/virtfs.cpp
+++ b/src/fs/virtfs/virtfs.cpp
@@ -161,6 +161,28 @@ namespace VirtFs
return list;
}
+ void getFiles(std::string dirName,
+ StringVect &list)
+ {
+ prepareFsPath(dirName);
+ if (checkPath(dirName) == false)
+ {
+ reportAlways("VirtFs::enumerateFiles invalid path: %s",
+ dirName.c_str());
+ return;
+ }
+
+ std::string rootDir = dirName;
+ if (findLast(rootDir, std::string(dirSeparator)) == false)
+ rootDir += dirSeparator;
+
+ FOR_EACH (std::vector<VirtFsEntry*>::const_iterator, it, mEntries)
+ {
+ VirtFsEntry *const entry = *it;
+ entry->funcs->getFiles(entry, rootDir, list);
+ }
+ }
+
bool isDirectory(std::string name)
{
prepareFsPath(name);
diff --git a/src/fs/virtfs/virtfs.h b/src/fs/virtfs/virtfs.h
index ca74206e8..7f9600b88 100644
--- a/src/fs/virtfs/virtfs.h
+++ b/src/fs/virtfs/virtfs.h
@@ -25,10 +25,9 @@
#include "enums/simpletypes/append.h"
-#include "localconsts.h"
+#include "utils/stringvector.h"
-#include <string>
-#include <vector>
+#include "localconsts.h"
struct VirtFile;
struct VirtFsEntry;
@@ -95,6 +94,8 @@ namespace VirtFs
#endif // UNITTESTS
const char *loadFile(std::string filename,
int &restrict fileSize);
+ void getFiles(std::string path,
+ StringVect &list);
} // namespace VirtFs
extern const char *dirSeparator;
diff --git a/src/fs/virtfs/virtfs1_unittest.cc b/src/fs/virtfs/virtfs1_unittest.cc
index d7a0d341c..a267f2b5a 100644
--- a/src/fs/virtfs/virtfs1_unittest.cc
+++ b/src/fs/virtfs/virtfs1_unittest.cc
@@ -684,6 +684,17 @@ static bool inList(const VirtList *const list,
return false;
}
+static bool inList(StringVect list,
+ const std::string &name)
+{
+ FOR_EACH (StringVectCIter, it, list)
+ {
+ if (*it == name)
+ return true;
+ }
+ return false;
+}
+
TEST_CASE("VirtFs1 enumerateFiles1")
{
VirtFs::init(".");
@@ -919,6 +930,37 @@ TEST_CASE("VirtFsZip enumerateFiles8")
delete2(logger);
}
+TEST_CASE("VirtFsZip enumerateFiles9")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+ VirtFs::mountDirSilent(prefix + "data/test",
+ Append_false);
+
+ VirtList *list = nullptr;
+
+ list = VirtFs::enumerateFiles("dir");
+ REQUIRE(list->names.size() == 4);
+ REQUIRE(inList(list, "1"));
+ REQUIRE(inList(list, "gpl"));
+ REQUIRE(inList(list, "dye.png"));
+ REQUIRE(inList(list, "hide.png"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::unmountDir(prefix + "data/test");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+
TEST_CASE("VirtFs1 isDirectory1")
{
VirtFs::init(".");
@@ -1872,3 +1914,34 @@ TEST_CASE("VirtFs1 rwops_read3")
VirtFs::deinit();
delete2(logger);
}
+
+TEST_CASE("VirtFs1 getFiles zip")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+
+ StringVect list;
+ VirtFs::getFiles("dir", list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "dye.png"));
+ REQUIRE(inList(list, "hide.png"));
+
+ list.clear();
+ VirtFs::getFiles("dir2", list);
+ REQUIRE(inList(list, "hide.png"));
+ REQUIRE(inList(list, "paths.xml"));
+ REQUIRE(inList(list, "test.txt"));
+ REQUIRE(inList(list, "units.xml"));
+ REQUIRE(list.size() == 4);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
diff --git a/src/fs/virtfs/virtfsdir.cpp b/src/fs/virtfs/virtfsdir.cpp
index 9eac0896b..2d165195e 100644
--- a/src/fs/virtfs/virtfsdir.cpp
+++ b/src/fs/virtfs/virtfsdir.cpp
@@ -137,6 +137,7 @@ namespace VirtFsDir
ptr->openWrite = &VirtFsDir::openWrite;
ptr->openAppend = &VirtFsDir::openAppend;
ptr->loadFile = &VirtFsDir::loadFile;
+ ptr->getFiles = &VirtFsDir::getFiles;
ptr->rwops_seek = &VirtFsDir::rwops_seek;
ptr->rwops_read = &VirtFsDir::rwops_read;
ptr->rwops_write = &VirtFsDir::rwops_write;
@@ -511,4 +512,54 @@ namespace VirtFsDir
return buffer;
}
+
+ void getFiles(VirtFsEntry *restrict const entry,
+ const std::string &dirName,
+ StringVect &names)
+ {
+ const std::string path = entry->root + dirName;
+ const struct dirent *next_file = nullptr;
+ DIR *const dir = opendir(path.c_str());
+ if (dir)
+ {
+ while ((next_file = readdir(dir)))
+ {
+ struct stat statbuf;
+ const std::string file = next_file->d_name;
+ if (file == "." || file == "..")
+ continue;
+#ifndef WIN32
+ if (mPermitLinks == false)
+ {
+ if (lstat(path.c_str(), &statbuf) == 0 &&
+ S_ISLNK(statbuf.st_mode) != 0)
+ {
+ continue;
+ }
+ }
+#endif // WIN32
+
+ const std::string filePath = pathJoin(path, file);
+ if (stat(filePath.c_str(), &statbuf) == 0)
+ {
+ if (S_ISDIR(statbuf.st_mode) != 0)
+ continue;
+ }
+
+ bool found(false);
+ FOR_EACH (StringVectCIter, itn, names)
+ {
+ if (*itn == file)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found == false)
+ names.push_back(file);
+ }
+ closedir(dir);
+ }
+ }
+
} // namespace VirtFs
diff --git a/src/fs/virtfs/virtfsdir.h b/src/fs/virtfs/virtfsdir.h
index 37e472a12..2a7829bb1 100644
--- a/src/fs/virtfs/virtfsdir.h
+++ b/src/fs/virtfs/virtfsdir.h
@@ -55,6 +55,9 @@ namespace VirtFsDir
void enumerate(VirtFsEntry *restrict const entry,
const std::string &dirName,
StringVect &names);
+ void getFiles(VirtFsEntry *restrict const entry,
+ const std::string &dirName,
+ StringVect &names);
bool isDirectory(VirtFsEntry *restrict const entry,
const std::string &dirName,
bool &isDirFlag);
diff --git a/src/fs/virtfs/virtfsfuncs.h b/src/fs/virtfs/virtfsfuncs.h
index 84345679b..47d765c5c 100644
--- a/src/fs/virtfs/virtfsfuncs.h
+++ b/src/fs/virtfs/virtfsfuncs.h
@@ -43,6 +43,7 @@ struct VirtFsFuncs final
exists(nullptr),
getRealDir(nullptr),
enumerate(nullptr),
+ getFiles(nullptr),
isDirectory(nullptr),
openRead(nullptr),
openWrite(nullptr),
@@ -84,6 +85,9 @@ struct VirtFsFuncs final
void (*enumerate) (VirtFsEntry *restrict const entry,
const std::string &dirName,
StringVect &names);
+ void (*getFiles) (VirtFsEntry *restrict const entry,
+ const std::string &dirName,
+ StringVect &names);
bool (*isDirectory) (VirtFsEntry *restrict const entry,
const std::string &dirName,
bool &isDirFlag);
diff --git a/src/fs/virtfs/virtfstools.cpp b/src/fs/virtfs/virtfstools.cpp
index ca65bbdf2..12b261320 100644
--- a/src/fs/virtfs/virtfstools.cpp
+++ b/src/fs/virtfs/virtfstools.cpp
@@ -104,18 +104,6 @@ namespace VirtFs
std::sort(list.begin(), list.end());
}
- void getFiles(const std::string &path,
- StringVect &list)
- {
- VirtList *const fonts = VirtFs::enumerateFiles(path);
- FOR_EACH (StringVectCIter, i, fonts->names)
- {
- if (!VirtFs::isDirectory(pathJoin(path, *i)))
- list.push_back(*i);
- }
- VirtFs::freeList(fonts);
- }
-
void getDirs(const std::string &path, StringVect &list)
{
VirtList *const fonts = VirtFs::enumerateFiles(path);
diff --git a/src/fs/virtfs/virtfstools.h b/src/fs/virtfs/virtfstools.h
index 7ed9b7c66..fe9eb7ecf 100644
--- a/src/fs/virtfs/virtfstools.h
+++ b/src/fs/virtfs/virtfstools.h
@@ -39,8 +39,6 @@ namespace VirtFs
const std::string &ext);
void getFilesWithDir(const std::string &restrict path,
StringVect &restrict list);
- void getFiles(const std::string &path,
- StringVect &list);
void getDirs(const std::string &path,
StringVect &list);
std::string getPath(const std::string &file);
diff --git a/src/fs/virtfs/virtfszip.cpp b/src/fs/virtfs/virtfszip.cpp
index f2cacc34f..ae31f2606 100644
--- a/src/fs/virtfs/virtfszip.cpp
+++ b/src/fs/virtfs/virtfszip.cpp
@@ -21,6 +21,7 @@
#include "fs/virtfs/virtfszip.h"
#include "fs/virtfs/virtfile.h"
+#include "fs/virtfs/virtfs.h"
#include "fs/virtfs/virtfsfuncs.h"
#include "fs/virtfs/virtfsziprwops.h"
#include "fs/virtfs/virtlist.h"
@@ -73,6 +74,7 @@ namespace VirtFsZip
ptr->openWrite = &VirtFsZip::openWrite;
ptr->openAppend = &VirtFsZip::openAppend;
ptr->loadFile = &VirtFsZip::loadFile;
+ ptr->getFiles = &VirtFsZip::getFiles;
ptr->rwops_seek = &VirtFsZip::rwops_seek;
ptr->rwops_read = &VirtFsZip::rwops_read;
ptr->rwops_write = &VirtFsZip::rwops_write;
@@ -193,6 +195,98 @@ namespace VirtFsZip
}
}
+ void getFiles(VirtFsEntry *restrict const entry,
+ const std::string &dirName,
+ StringVect &names)
+ {
+ VirtZipEntry *const zipEntry = static_cast<VirtZipEntry*>(entry);
+ if (dirName == dirSeparator)
+ {
+ FOR_EACH (std::vector<ZipLocalHeader*>::const_iterator,
+ it2,
+ zipEntry->mHeaders)
+ {
+ ZipLocalHeader *const header = *it2;
+ std::string fileName = header->fileName;
+ // skip subdirs from enumeration
+ const size_t idx = fileName.find(dirSeparator);
+ if (idx != std::string::npos)
+ fileName.erase(idx);
+ bool found(false);
+ FOR_EACH (StringVectCIter, itn, names)
+ {
+ if (*itn == fileName)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found == false)
+ {
+ std::string dirName2 = pathJoin(dirName, fileName);
+ if (findLast(dirName2, std::string(dirSeparator)) == false)
+ dirName2 += dirSeparator;
+ FOR_EACH (std::vector<std::string>::const_iterator,
+ it,
+ zipEntry->mDirs)
+ {
+ if (*it == dirName2)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found == false)
+ names.push_back(fileName);
+ }
+ }
+ }
+ else
+ {
+ FOR_EACH (std::vector<ZipLocalHeader*>::const_iterator,
+ it2,
+ zipEntry->mHeaders)
+ {
+ ZipLocalHeader *const header = *it2;
+ std::string fileName = header->fileName;
+ if (findCutFirst(fileName, dirName) == true)
+ {
+ // skip subdirs from enumeration
+ const size_t idx = fileName.find(dirSeparator);
+ if (idx != std::string::npos)
+ fileName.erase(idx);
+ bool found(false);
+ FOR_EACH (StringVectCIter, itn, names)
+ {
+ if (*itn == fileName)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found == false)
+ {
+ std::string dirName2 = pathJoin(dirName, fileName);
+ if (findLast(dirName2, std::string(dirSeparator)) == false)
+ dirName2 += dirSeparator;
+ FOR_EACH (std::vector<std::string>::const_iterator,
+ it,
+ zipEntry->mDirs)
+ {
+ if (*it == dirName2)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found == false)
+ names.push_back(fileName);
+ }
+ }
+ }
+ }
+ }
+
bool isDirectory(VirtFsEntry *restrict const entry,
const std::string &dirName,
bool &isDirFlag)
diff --git a/src/fs/virtfs/virtfszip.h b/src/fs/virtfs/virtfszip.h
index bf2d75f3a..8efa82a50 100644
--- a/src/fs/virtfs/virtfszip.h
+++ b/src/fs/virtfs/virtfszip.h
@@ -42,6 +42,9 @@ namespace VirtFsZip
void enumerate(VirtFsEntry *restrict const entry,
const std::string &dirName,
StringVect &names);
+ void getFiles(VirtFsEntry *restrict const entry,
+ const std::string &dirName,
+ StringVect &names);
bool isDirectory(VirtFsEntry *restrict const entry,
const std::string &dirName,
bool &isDirFlag);