diff options
author | Andrei Karas <akaras@inbox.ru> | 2017-03-04 00:27:54 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2017-03-04 01:12:19 +0300 |
commit | 79bb654b80d5eb7a65814f80b9ca7ca1ccd62a00 (patch) | |
tree | f9669ee10e2ea3f2c41abaa84830da9efe7f9411 /src/fs/virtfs/virtfszip.cpp | |
parent | a6c70dd1f32c38cc81cfd4b28f929d7c13d86db1 (diff) | |
download | mv-79bb654b80d5eb7a65814f80b9ca7ca1ccd62a00.tar.gz mv-79bb654b80d5eb7a65814f80b9ca7ca1ccd62a00.tar.bz2 mv-79bb654b80d5eb7a65814f80b9ca7ca1ccd62a00.tar.xz mv-79bb654b80d5eb7a65814f80b9ca7ca1ccd62a00.zip |
Reimplement VirtFs in correct way. Now all tests should pass.
Diffstat (limited to 'src/fs/virtfs/virtfszip.cpp')
-rw-r--r-- | src/fs/virtfs/virtfszip.cpp | 184 |
1 files changed, 175 insertions, 9 deletions
diff --git a/src/fs/virtfs/virtfszip.cpp b/src/fs/virtfs/virtfszip.cpp index 8ee39a8d9..881e028cc 100644 --- a/src/fs/virtfs/virtfszip.cpp +++ b/src/fs/virtfs/virtfszip.cpp @@ -102,6 +102,11 @@ namespace VirtFsZip return nullptr; } + VirtFsFuncs *getFuncs() + { + return &funcs; + } + bool addToSearchPathSilent(std::string newDir, const Append append) { @@ -125,7 +130,7 @@ namespace VirtFsZip newDir.c_str()); return false; } - entry = new VirtZipEntry(newDir); + entry = new VirtZipEntry(newDir, &funcs); if (Zip::readArchiveInfo(entry) == false) { delete entry; @@ -166,7 +171,7 @@ namespace VirtFsZip newDir.c_str()); return false; } - entry = new VirtZipEntry(newDir); + entry = new VirtZipEntry(newDir, &funcs); if (Zip::readArchiveInfo(entry) == false) { delete entry; @@ -259,6 +264,13 @@ namespace VirtFsZip ptr->tell = &VirtFsZip::tell; ptr->seek = &VirtFsZip::seek; ptr->eof = &VirtFsZip::eof; + ptr->exists = &VirtFsZip::exists; + ptr->getRealDir = &VirtFsZip::getRealDir; + ptr->enumerate = &VirtFsZip::enumerate; + ptr->isDirectory = &VirtFsZip::isDirectory; + ptr->openRead = &VirtFsZip::openRead; + ptr->openWrite = &VirtFsZip::openWrite; + ptr->openAppend = &VirtFsZip::openAppend; } std::string getRealDir(std::string filename) @@ -282,6 +294,35 @@ namespace VirtFsZip return std::string(); } + bool getRealDir(VirtFsEntry *restrict const entry, + const std::string &filename, + const std::string &dirName, + std::string &realDir) + { + VirtZipEntry *const zipEntry = static_cast<VirtZipEntry*>(entry); + FOR_EACH (std::vector<ZipLocalHeader*>::const_iterator, + it2, + zipEntry->mHeaders) + { + if ((*it2)->fileName == filename) + { + realDir = entry->root; + return true; + } + } + FOR_EACH (std::vector<std::string>::const_iterator, + it2, + zipEntry->mDirs) + { + if (*it2 == dirName) + { + realDir = entry->root; + return true; + } + } + return false; + } + bool exists(std::string name) { prepareFsPath(name); @@ -296,6 +337,28 @@ namespace VirtFsZip return entry != nullptr; } + bool exists(VirtFsEntry *restrict const entry, + const std::string &filename, + const std::string &dirName) + { + VirtZipEntry *const zipEntry = static_cast<VirtZipEntry*>(entry); + FOR_EACH (std::vector<ZipLocalHeader*>::const_iterator, + it2, + zipEntry->mHeaders) + { + if ((*it2)->fileName == filename) + return true; + } + FOR_EACH (std::vector<std::string>::const_iterator, + it2, + zipEntry->mDirs) + { + if (*it2 == dirName) + return true; + } + return false; + } + VirtList *enumerateFiles(std::string dirName) { VirtList *const list = new VirtList; @@ -309,6 +372,66 @@ namespace VirtFsZip return enumerateFiles(dirName, list); } + void enumerate(VirtFsEntry *restrict const entry, + const std::string &dirName, + StringVect &names) + { + VirtZipEntry *const zipEntry = static_cast<VirtZipEntry*>(entry); + if (dirName == "/") + { + 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) + 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) + names.push_back(fileName); + } + } + } + } + VirtList *enumerateFiles(std::string dirName, VirtList *restrict const list) { @@ -380,16 +503,22 @@ namespace VirtFsZip return list; } - bool isDirectory(std::string dirName) + bool isDirectory(VirtFsEntry *restrict const entry, + const std::string &dirName, + bool &isDirFlag) { - prepareFsPath(dirName); - if (checkPath(dirName) == false) + VirtZipEntry *const zipEntry = static_cast<VirtZipEntry*>(entry); + FOR_EACH (std::vector<std::string>::const_iterator, + it2, + zipEntry->mDirs) { - reportAlways("VirtFsZip::isDirectory invalid path: %s", - dirName.c_str()); - return false; + if (*it2 == dirName) + { + isDirFlag = true; + return true; + } } - return isDirectoryInternal(dirName); + return false; } bool isDirectoryInternal(std::string dirName) @@ -440,6 +569,43 @@ namespace VirtFsZip return openReadInternal(filename); } + VirtFile *openRead(VirtFsEntry *restrict const entry, + const std::string &filename) + { + VirtZipEntry *const zipEntry = static_cast<VirtZipEntry*>(entry); + FOR_EACH (std::vector<ZipLocalHeader*>::const_iterator, + it2, + zipEntry->mHeaders) + { + ZipLocalHeader *restrict const header = *it2; + if (header->fileName == filename) + { + uint8_t *restrict const buf = Zip::readFile(header); + if (buf == nullptr) + return nullptr; + VirtFile *restrict const file = new VirtFile(&funcs); + file->mPrivate = new VirtFilePrivate(buf, + header->uncompressSize); + return file; + } + } + return nullptr; + } + + VirtFile *openWrite(VirtFsEntry *restrict const entry, + const std::string &filename) + { + reportAlways("VirtFs::openWrite for zip not implemented."); + return nullptr; + } + + VirtFile *openAppend(VirtFsEntry *restrict const entry, + const std::string &filename) + { + reportAlways("VirtFs::openAppend for zip not implemented."); + return nullptr; + } + VirtFile *openReadInternal(const std::string &filename) { ZipLocalHeader *restrict const header = searchHeaderByName(filename); |