diff options
Diffstat (limited to 'src/fs/physfs')
-rw-r--r-- | src/fs/physfs/virtfileprivate.cpp | 28 | ||||
-rw-r--r-- | src/fs/physfs/virtfileprivate.h | 43 | ||||
-rw-r--r-- | src/fs/physfs/virtfs.cpp | 207 | ||||
-rw-r--r-- | src/fs/physfs/virtfsphys.cpp | 327 | ||||
-rw-r--r-- | src/fs/physfs/virtfsphys.h | 80 | ||||
-rw-r--r-- | src/fs/physfs/virtfsphys_unittest.cc | 539 |
6 files changed, 1224 insertions, 0 deletions
diff --git a/src/fs/physfs/virtfileprivate.cpp b/src/fs/physfs/virtfileprivate.cpp new file mode 100644 index 000000000..9df6e9578 --- /dev/null +++ b/src/fs/physfs/virtfileprivate.cpp @@ -0,0 +1,28 @@ +/* + * The ManaPlus Client + * Copyright (C) 2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "fs/physfs/virtfileprivate.h" + +#include "debug.h" + +VirtFilePrivate::VirtFilePrivate(PHYSFS_file *restrict const file) : + mFile(file) +{ +} diff --git a/src/fs/physfs/virtfileprivate.h b/src/fs/physfs/virtfileprivate.h new file mode 100644 index 000000000..75ad6a337 --- /dev/null +++ b/src/fs/physfs/virtfileprivate.h @@ -0,0 +1,43 @@ +/* + * The ManaPlus Client + * Copyright (C) 2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UTILS_VIRTFILEPRIVATE_H +#define UTILS_VIRTFILEPRIVATE_H + +#include "localconsts.h" + +PRAGMA45(GCC diagnostic push) +PRAGMA45(GCC diagnostic ignored "-Wlong-long") +#include <physfs.h> +PRAGMA45(GCC diagnostic pop) + +struct VirtFilePrivate final +{ + explicit VirtFilePrivate(PHYSFS_file *restrict const file); + + A_DELETE_COPY(VirtFilePrivate) + + ~VirtFilePrivate(); + + // physfs fields + PHYSFS_file *mFile; +}; + +#endif // UTILS_VIRTFILEPRIVATE_H diff --git a/src/fs/physfs/virtfs.cpp b/src/fs/physfs/virtfs.cpp new file mode 100644 index 000000000..7a1484081 --- /dev/null +++ b/src/fs/physfs/virtfs.cpp @@ -0,0 +1,207 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013-2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "fs/virtfs.h" + +#include "fs/physfs/virtfsphys.h" +#include "fs/virtfile.h" +#include "fs/virtfsfuncs.h" +#include "fs/virtlist.h" + +#include "debug.h" + +const char *dirSeparator = nullptr; + +namespace VirtFs +{ + void init(const std::string &restrict name) + { + VirtFsPhys::init(name); + updateDirSeparator(); + } + + void updateDirSeparator() + { + dirSeparator = VirtFsPhys::getDirSeparator(); + } + + const char *getDirSeparator() + { + return dirSeparator; + } + + const char *getBaseDir() + { + return VirtFsPhys::getBaseDir(); + } + + const char *getUserDir() + { + return VirtFsPhys::getUserDir(); + } + + bool exists(const std::string &restrict name) + { + return VirtFsPhys::exists(name); + } + + VirtList *enumerateFiles(std::string dirName) + { + return VirtFsPhys::enumerateFiles(dirName); + } + + bool isDirectory(std::string name) + { + return VirtFsPhys::isDirectory(name); + } + + bool isSymbolicLink(const std::string &restrict name) + { + return VirtFsPhys::isSymbolicLink(name); + } + + void freeList(VirtList *restrict const handle) + { + delete handle; + } + + VirtFile *openRead(std::string filename) + { + return VirtFsPhys::openRead(filename); + } + + VirtFile *openWrite(const std::string &restrict filename) + { + return VirtFsPhys::openWrite(filename); + } + + VirtFile *openAppend(const std::string &restrict filename) + { + return VirtFsPhys::openAppend(filename); + } + + bool setWriteDir(const std::string &restrict newDir) + { + return VirtFsPhys::setWriteDir(newDir); + } + + bool addDirToSearchPath(const std::string &restrict newDir, + const Append append) + { + return VirtFsPhys::addDirToSearchPath(newDir, append); + } + + bool removeDirFromSearchPath(const std::string &restrict oldDir) + { + return VirtFsPhys::removeDirFromSearchPath(oldDir); + } + + bool addZipToSearchPath(const std::string &restrict newDir, + const Append append) + { + return VirtFsPhys::addZipToSearchPath(newDir, append); + } + + bool removeZipFromSearchPath(const std::string &restrict oldDir) + { + return VirtFsPhys::removeZipFromSearchPath(oldDir); + } + + std::string getRealDir(std::string filename) + { + return VirtFsPhys::getRealDir(filename); + } + + bool mkdir(const std::string &restrict dirname) + { + return VirtFsPhys::mkdir(dirname); + } + + bool remove(const std::string &restrict filename) + { + return VirtFsPhys::remove(filename); + } + + bool deinit() + { + return VirtFsPhys::deinit(); + } + + void permitLinks(const bool val) + { + VirtFsPhys::permitLinks(val); + } + + const char *getLastError() + { + return VirtFsPhys::getLastError(); + } + + int close(VirtFile *restrict const file) + { + if (file == nullptr) + return 0; + return file->funcs->close(file); + } + + int64_t read(VirtFile *restrict const file, + void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount) + { + return file->funcs->read(file, + buffer, + objSize, + objCount); + } + + int64_t write(VirtFile *restrict const file, + const void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount) + { + return file->funcs->write(file, + buffer, + objSize, + objCount); + } + + int64_t fileLength(VirtFile *restrict const file) + { + return file->funcs->fileLength(file); + } + + int64_t tell(VirtFile *restrict const file) + { + return file->funcs->tell(file); + } + + int seek(VirtFile *restrict const file, + const uint64_t pos) + { + return file->funcs->seek(file, + pos); + } + + int eof(VirtFile *restrict const file) + { + return file->funcs->eof(file); + } +} // namespace VirtFs diff --git a/src/fs/physfs/virtfsphys.cpp b/src/fs/physfs/virtfsphys.cpp new file mode 100644 index 000000000..3cb044277 --- /dev/null +++ b/src/fs/physfs/virtfsphys.cpp @@ -0,0 +1,327 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013-2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "fs/physfs/virtfsphys.h" + +#include "fs/virtfile.h" +#include "fs/virtfsfuncs.h" +#include "fs/virtlist.h" + +#include "fs/physfs/virtfileprivate.h" + +#include "utils/checkutils.h" + +#include <iostream> +#include <unistd.h> + +#ifdef ANDROID +#include "fs/paths.h" +#endif // ANDROID + +#include "debug.h" + +namespace +{ + const char *dirSeparator = nullptr; + VirtFsFuncs funcs; +} // namespace + +namespace VirtFsPhys +{ +#if defined(__native_client__) + void init(const std::string &restrict name A_UNUSED) + { + if (!PHYSFS_init("/fakebinary")) +#elif defined(ANDROID) + void init(const std::string &restrict name A_UNUSED) + { + if (!PHYSFS_init((getRealPath(".").append("/fakebinary")).c_str())) +#else // defined(__native_client__) + + void init(const std::string &restrict name) + { + if (!PHYSFS_init(name.c_str())) +#endif // defined(__native_client__) + { + std::cout << "Error while initializing PhysFS: " + << VirtFsPhys::getLastError() << std::endl; + _exit(1); + } + updateDirSeparator(); + atexit(reinterpret_cast<void(*)()>(PHYSFS_deinit)); + initFuncs(&funcs); + } + + void initFuncs() + { + initFuncs(&funcs); + } + + void initFuncs(VirtFsFuncs *restrict const ptr) + { + ptr->close = &VirtFsPhys::close; + ptr->read = &VirtFsPhys::read; + ptr->write = &VirtFsPhys::write; + ptr->fileLength = &VirtFsPhys::fileLength; + ptr->tell = &VirtFsPhys::tell; + ptr->seek = &VirtFsPhys::seek; + ptr->eof = &VirtFsPhys::eof; + } + + void updateDirSeparator() + { + dirSeparator = PHYSFS_getDirSeparator(); + } + + const char *getDirSeparator() + { + return dirSeparator; + } + + const char *getBaseDir() + { + return PHYSFS_getBaseDir(); + } + + const char *getUserDir() + { + return PHYSFS_getUserDir(); + } + + bool exists(const std::string &restrict name) + { + return PHYSFS_exists(name.c_str()); + } + + VirtList *enumerateFiles(const std::string &restrict dir) + { + char ** handle = PHYSFS_enumerateFiles(dir.c_str()); + VirtList *const files = new VirtList; + if (handle == nullptr) + return files; + for (const char *const *i = handle; *i; i++) + { + std::string str = *i; + files->names.push_back(str); + } + PHYSFS_freeList(handle); + return files; + } + + bool isDirectory(const std::string &restrict name) + { + return PHYSFS_isDirectory(name.c_str()); + } + + bool isSymbolicLink(const std::string &restrict name) + { + return PHYSFS_isSymbolicLink(name.c_str()); + } + + void freeList(VirtList *restrict const handle) + { + delete handle; + } + + VirtFile *openRead(const std::string &restrict filename) + { + PHYSFS_file *restrict const handle = PHYSFS_openRead( + filename.c_str()); + if (!handle) + return nullptr; + VirtFile *restrict const file = new VirtFile(&funcs); + file->mPrivate = new VirtFilePrivate(handle); + return file; + } + + VirtFile *openWrite(const std::string &restrict filename) + { + PHYSFS_file *restrict const handle = PHYSFS_openWrite( + filename.c_str()); + if (!handle) + return nullptr; + VirtFile *restrict const file = new VirtFile(&funcs); + file->mPrivate = new VirtFilePrivate(handle); + return file; + } + + VirtFile *openAppend(const std::string &restrict filename) + { + PHYSFS_file *restrict const handle = PHYSFS_openAppend( + filename.c_str()); + if (!handle) + return nullptr; + VirtFile *restrict const file = new VirtFile(&funcs); + file->mPrivate = new VirtFilePrivate(handle); + return file; + } + + bool setWriteDir(const std::string &restrict newDir) + { + return PHYSFS_setWriteDir(newDir.c_str()); + } + + bool addDirToSearchPath(const std::string &restrict newDir, + const Append append) + { + logger->log("Add virtual directory: " + newDir); + if (newDir.find(".zip") != std::string::npos) + { + reportAlways("Called addDirToSearchPath with zip archive"); + return false; + } + return PHYSFS_addToSearchPath(newDir.c_str(), + append == Append_true ? 1 : 0); + } + + bool removeDirFromSearchPath(const std::string &restrict oldDir) + { + logger->log("Remove virtual directory: " + oldDir); + if (oldDir.find(".zip") != std::string::npos) + { + reportAlways("Called removeDirFromSearchPath with zip archive"); + return false; + } + return PHYSFS_removeFromSearchPath(oldDir.c_str()); + } + + bool addZipToSearchPath(const std::string &restrict newDir, + const Append append) + { + logger->log("Add virtual zip: " + newDir); + if (newDir.find(".zip") == std::string::npos) + { + reportAlways("Called addZipToSearchPath without zip archive"); + return false; + } + return PHYSFS_addToSearchPath(newDir.c_str(), + append == Append_true ? 1 : 0); + } + + bool removeZipFromSearchPath(const std::string &restrict oldDir) + { + logger->log("Remove virtual zip: " + oldDir); + if (oldDir.find(".zip") == std::string::npos) + { + reportAlways("Called removeZipFromSearchPath without zip archive"); + return false; + } + return PHYSFS_removeFromSearchPath(oldDir.c_str()); + } + + std::string getRealDir(const std::string &restrict filename) + { + const char *const str = PHYSFS_getRealDir(filename.c_str()); + if (str == nullptr) + return std::string(); + return str; + } + + bool mkdir(const std::string &restrict dirname) + { + return PHYSFS_mkdir(dirname.c_str()); + } + + bool remove(const std::string &restrict filename) + { + return PHYSFS_delete(filename.c_str()); + } + + bool deinit() + { + if (PHYSFS_deinit() != 0) + { + logger->log("Physfs deinit error: %s", + VirtFsPhys::getLastError()); + return false; + } + return true; + } + + void permitLinks(const bool val) + { + PHYSFS_permitSymbolicLinks(val ? 1 : 0); + } + + const char *getLastError() + { + return PHYSFS_getLastError(); + } + + int close(VirtFile *restrict const file) + { + if (file == nullptr) + return 0; + delete file; + return 1; + } + + int64_t read(VirtFile *restrict const file, + void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount) + { + if (file == nullptr) + return 0; + return PHYSFS_read(file->mPrivate->mFile, + buffer, + objSize, + objCount); + } + + int64_t write(VirtFile *restrict const file, + const void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount) + { + if (file == nullptr) + return 0; + return PHYSFS_write(file->mPrivate->mFile, + buffer, + objSize, + objCount); + } + + int64_t fileLength(VirtFile *restrict const file) + { + if (file == nullptr) + return -1; + return PHYSFS_fileLength(file->mPrivate->mFile); + } + + int64_t tell(VirtFile *restrict const file) + { + if (file == nullptr) + return -1; + return PHYSFS_tell(file->mPrivate->mFile); + } + + int seek(VirtFile *restrict const file, + const uint64_t pos) + { + return PHYSFS_seek(file->mPrivate->mFile, + pos); + } + + int eof(VirtFile *restrict const file) + { + return PHYSFS_eof(file->mPrivate->mFile); + } +} // namespace VirtFsPhys diff --git a/src/fs/physfs/virtfsphys.h b/src/fs/physfs/virtfsphys.h new file mode 100644 index 000000000..743530c6c --- /dev/null +++ b/src/fs/physfs/virtfsphys.h @@ -0,0 +1,80 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013-2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UTILS_VIRTFSPHYS_H +#define UTILS_VIRTFSPHYS_H + +#include "enums/simpletypes/append.h" + +#include "localconsts.h" + +#include <string> + +struct VirtFile; +struct VirtFsFuncs; +struct VirtList; + +namespace VirtFsPhys +{ + void init(const std::string &restrict name); + void initFuncs(VirtFsFuncs *restrict const ptr); + void initFuncs(); + void updateDirSeparator(); + const char *getDirSeparator(); + const char *getBaseDir(); + const char *getUserDir(); + bool exists(const std::string &restrict name); + VirtList *enumerateFiles(const std::string &restrict dir) RETURNS_NONNULL; + bool isDirectory(const std::string &restrict name); + bool isSymbolicLink(const std::string &restrict name); + void freeList(VirtList *restrict const handle); + VirtFile *openRead(const std::string &restrict filename); + VirtFile *openWrite(const std::string &restrict filename); + VirtFile *openAppend(const std::string &restrict filename); + bool setWriteDir(const std::string &restrict newDir); + bool addDirToSearchPath(const std::string &restrict newDir, + const Append append); + bool removeDirFromSearchPath(const std::string &restrict oldDir); + bool addZipToSearchPath(const std::string &restrict newDir, + const Append append); + bool removeZipFromSearchPath(const std::string &restrict oldDir); + std::string getRealDir(const std::string &restrict filename); + bool mkdir(const std::string &restrict dirName); + bool remove(const std::string &restrict filename); + bool deinit(); + void permitLinks(const bool val); + const char *getLastError(); + int64_t read(VirtFile *restrict const handle, + void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount); + int64_t write(VirtFile *restrict const file, + const void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount); + int close(VirtFile *restrict const file); + int64_t fileLength(VirtFile *restrict const file); + int64_t tell(VirtFile *restrict const file); + int seek(VirtFile *restrict const file, + const uint64_t pos); + int eof(VirtFile *restrict const file); +} // namespace VirtFsPhys + +#endif // UTILS_VIRTFSPHYS_H diff --git a/src/fs/physfs/virtfsphys_unittest.cc b/src/fs/physfs/virtfsphys_unittest.cc new file mode 100644 index 000000000..8e81cfe2b --- /dev/null +++ b/src/fs/physfs/virtfsphys_unittest.cc @@ -0,0 +1,539 @@ +/* + * The ManaPlus Client + * Copyright (C) 2016-2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "catch.hpp" + +#include "fs/paths.h" +#include "fs/virtfs.h" +#include "fs/virtfstools.h" +#include "fs/virtlist.h" + +#include "fs/physfs/virtfsphys.h" + +#include "utils/checkutils.h" +#include "utils/delete2.h" + +#include "debug.h" + +TEST_CASE("VirtFsPhys dirSeparator") +{ + VirtFsPhys::initFuncs(); + REQUIRE(VirtFs::getDirSeparator() != nullptr); + REQUIRE(VirtFsPhys::getDirSeparator() == + std::string(VirtFs::getDirSeparator())); + VirtFsPhys::updateDirSeparator(); + REQUIRE(VirtFs::getDirSeparator() != nullptr); + REQUIRE(VirtFsPhys::getDirSeparator() == + std::string(VirtFs::getDirSeparator())); +} + +TEST_CASE("VirtFsPhys getBaseDir") +{ + VirtFsPhys::initFuncs(); + REQUIRE(VirtFsPhys::getBaseDir() != nullptr); +} + +TEST_CASE("VirtFsPhys getUserDir") +{ + VirtFsPhys::initFuncs(); + REQUIRE(VirtFsPhys::getUserDir() != nullptr); + REQUIRE(VirtFsPhys::getUserDir() == getHomePath()); +} + +TEST_CASE("VirtFsPhys exists") +{ + VirtFsPhys::initFuncs(); + logger = new Logger(); + VirtFsPhys::addDirToSearchPath("data", Append_false); + VirtFsPhys::addDirToSearchPath("../data", Append_false); + + REQUIRE(VirtFsPhys::exists("test/units.xml") == true); + REQUIRE(VirtFsPhys::exists("test/units123.xml") == false); + REQUIRE(VirtFsPhys::exists("tesQ/units.xml") == false); + REQUIRE(VirtFsPhys::exists("units.xml") == false); + + VirtFsPhys::addDirToSearchPath("data/test", Append_false); + VirtFsPhys::addDirToSearchPath("../data/test", Append_false); + + REQUIRE(VirtFsPhys::exists("test/units.xml") == true); + REQUIRE(VirtFsPhys::exists("test/units123.xml") == false); + REQUIRE(VirtFsPhys::exists("tesQ/units.xml") == false); + REQUIRE(VirtFsPhys::exists("units.xml") == true); + + VirtFsPhys::removeDirFromSearchPath("data/test"); + VirtFsPhys::removeDirFromSearchPath("../data/test"); + + REQUIRE(VirtFsPhys::exists("test/units.xml") == true); + REQUIRE(VirtFsPhys::exists("test/units123.xml") == false); + REQUIRE(VirtFsPhys::exists("tesQ/units.xml") == false); + REQUIRE(VirtFsPhys::exists("units.xml") == false); + + VirtFsPhys::removeDirFromSearchPath("data"); + VirtFsPhys::removeDirFromSearchPath("../data"); + delete2(logger); +} + +TEST_CASE("VirtFsPhys exists2") +{ + VirtFsPhys::initFuncs(); + logger = new Logger(); + VirtFsPhys::addZipToSearchPath("data/test/test2.zip", Append_false); + VirtFsPhys::addZipToSearchPath("../data/test/test2.zip", Append_false); + + REQUIRE(VirtFsPhys::exists("test/units.xml") == false); + REQUIRE(VirtFsPhys::exists("test.txt") == true); + REQUIRE(VirtFsPhys::exists("units123.xml") == false); + REQUIRE(VirtFsPhys::exists("tesQ/units.xml") == false); + REQUIRE(VirtFsPhys::exists("units.xml") == true); + + VirtFsPhys::removeZipFromSearchPath("data/test/test2.zip"); + VirtFsPhys::removeZipFromSearchPath("../data/test/test2.zip"); + delete2(logger); +} + +static void removeTemp(StringVect &restrict list) +{ + int cnt = 0; + std::sort(list.begin(), list.end()); + + FOR_EACH (StringVectIter, it, list) + { + if (*it != "serverlistplus.xml.part") + { + logger->log("file: %d %s", + cnt, + (*it).c_str()); + cnt ++; + } + } + + FOR_EACH (StringVectIter, it, list) + { + if (*it == "serverlistplus.xml.part") + { + list.erase(it); + return; + } + } +} + +TEST_CASE("VirtFsPhys enumerateFiles1") +{ + VirtFsPhys::initFuncs(); + logger = new Logger; + + VirtFsPhys::addDirToSearchPath("data", Append_false); + VirtFsPhys::addDirToSearchPath("../data", Append_false); + + VirtList *list = nullptr; + + const int cnt1 = VirtFsPhys::exists("test/test2.txt") ? 27 : 26; + const int cnt2 = 27; + + VirtFsPhys::permitLinks(false); + list = VirtFsPhys::enumerateFiles("test"); + removeTemp(list->names); + const size_t sz = list->names.size(); + REQUIRE(sz == cnt1); + VirtFsPhys::freeList(list); + + VirtFsPhys::permitLinks(true); + list = VirtFsPhys::enumerateFiles("test"); + removeTemp(list->names); + REQUIRE(list->names.size() == cnt2); + VirtFsPhys::freeList(list); + + VirtFsPhys::permitLinks(false); + list = VirtFsPhys::enumerateFiles("test"); + removeTemp(list->names); + REQUIRE(list->names.size() == cnt1); + VirtFsPhys::freeList(list); + + VirtFsPhys::removeDirFromSearchPath("data"); + VirtFsPhys::removeDirFromSearchPath("../data"); + delete2(logger); +} + +TEST_CASE("VirtFsPhys enumerateFiles2") +{ + VirtFsPhys::initFuncs(); + logger = new Logger; + + VirtFsPhys::addDirToSearchPath("data/test/dir1", + Append_false); + VirtFsPhys::addDirToSearchPath("../data/test/dir1", + Append_false); + + VirtList *list = nullptr; + + list = VirtFsPhys::enumerateFiles("/"); + const size_t sz = list->names.size(); + REQUIRE(list->names.size() == 5); + VirtFsPhys::freeList(list); + + VirtFsPhys::removeDirFromSearchPath("data/test/dir1"); + VirtFsPhys::removeDirFromSearchPath("../data/test/dir1"); + delete2(logger); +} + +static bool inList(VirtList *list, + const std::string &name) +{ + FOR_EACH (StringVectCIter, it, list->names) + { + if (*it == name) + return true; + } + return false; +} + +TEST_CASE("VirtFsPhys enumerateFiles3") +{ + VirtFsPhys::initFuncs(); + logger = new Logger; + + VirtFsPhys::addZipToSearchPath("data/test/test.zip", + Append_false); + VirtFsPhys::addZipToSearchPath("../data/test/test.zip", + Append_false); + + VirtList *list = nullptr; + + list = VirtFsPhys::enumerateFiles("/"); + REQUIRE(inList(list, "units.xml") == false); + REQUIRE(inList(list, "test.txt") == false); + VirtFsPhys::freeList(list); + + VirtFsPhys::removeZipFromSearchPath("data/test/test.zip"); + VirtFsPhys::removeZipFromSearchPath("../data/test/test.zip"); + delete2(logger); +} + +TEST_CASE("VirtFsPhys enumerateFiles4") +{ + VirtFsPhys::initFuncs(); + logger = new Logger; + + VirtFsPhys::addZipToSearchPath("data/test/test2.zip", + Append_false); + VirtFsPhys::addZipToSearchPath("../data/test/test2.zip", + Append_false); + + VirtList *list = nullptr; + + list = VirtFsPhys::enumerateFiles("/"); + REQUIRE(inList(list, "units.xml") == true); + REQUIRE(inList(list, "test.txt") == true); + VirtFsPhys::freeList(list); + + VirtFsPhys::removeZipFromSearchPath("data/test/test2.zip"); + VirtFsPhys::removeZipFromSearchPath("../data/test/test2.zip"); + delete2(logger); +} + +TEST_CASE("VirtFsPhys isDirectory") +{ + VirtFsPhys::initFuncs(); + logger = new Logger(); + VirtFsPhys::addDirToSearchPath("data", Append_false); + VirtFsPhys::addDirToSearchPath("../data", Append_false); + + REQUIRE(VirtFsPhys::isDirectory("test/units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("test/units.xml/") == false); + REQUIRE(VirtFsPhys::isDirectory("test//units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("test/units123.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("test//units123.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("tesQ/units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("tesQ//units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("test") == true); + REQUIRE(VirtFsPhys::isDirectory("test/") == true); + REQUIRE(VirtFsPhys::isDirectory("test//") == true); + REQUIRE(VirtFsPhys::isDirectory("test/dir1") == true); + REQUIRE(VirtFsPhys::isDirectory("test//dir1") == true); + REQUIRE(VirtFsPhys::isDirectory("test//dir1/") == true); + REQUIRE(VirtFsPhys::isDirectory("test//dir1//") == true); + REQUIRE(VirtFsPhys::isDirectory("test/dir1/") == true); + REQUIRE(VirtFsPhys::isDirectory("test/dir1//") == true); + REQUIRE(VirtFsPhys::isDirectory("testQ") == false); + REQUIRE(VirtFsPhys::isDirectory("testQ/") == false); + REQUIRE(VirtFsPhys::isDirectory("testQ//") == false); + + VirtFsPhys::addDirToSearchPath("data/test", Append_false); + VirtFsPhys::addDirToSearchPath("../data/test", Append_false); + + REQUIRE(VirtFsPhys::isDirectory("test/units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("test/units.xml/") == false); + REQUIRE(VirtFsPhys::isDirectory("test//units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("test/units123.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("tesQ/units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("test") == true); + REQUIRE(VirtFsPhys::isDirectory("testQ") == false); + REQUIRE(VirtFsPhys::isDirectory("test/dir1") == true); + + VirtFsPhys::removeDirFromSearchPath("data/test"); + VirtFsPhys::removeDirFromSearchPath("../data/test"); + + REQUIRE(VirtFsPhys::isDirectory("test/units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("test/units123.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("tesQ/units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("units.xml") == false); + REQUIRE(VirtFsPhys::isDirectory("units.xml/") == false); + REQUIRE(VirtFsPhys::isDirectory("test") == true); + REQUIRE(VirtFsPhys::isDirectory("test/") == true); + REQUIRE(VirtFsPhys::isDirectory("testQ") == false); + REQUIRE(VirtFsPhys::isDirectory("test/dir1") == true); + + VirtFsPhys::removeDirFromSearchPath("data"); + VirtFsPhys::removeDirFromSearchPath("../data"); + delete2(logger); +} + +TEST_CASE("VirtFsPhys openRead") +{ + VirtFsPhys::initFuncs(); + logger = new Logger(); + VirtFsPhys::addDirToSearchPath("data", Append_false); + VirtFsPhys::addDirToSearchPath("../data", Append_false); + + VirtFile *file = nullptr; + + file = VirtFsPhys::openRead("test/units.xml"); + REQUIRE(file != nullptr); + VirtFsPhys::close(file); + file = VirtFsPhys::openRead("test/units123.xml"); + REQUIRE(file == nullptr); + file = VirtFsPhys::openRead("tesQ/units.xml"); + REQUIRE(file == nullptr); + file = VirtFsPhys::openRead("units.xml"); + REQUIRE(file == nullptr); +// file = VirtFsPhys::openRead("test"); +// REQUIRE(file == nullptr); + file = VirtFsPhys::openRead("testQ"); + REQUIRE(file == nullptr); + + VirtFsPhys::addDirToSearchPath("data/test", Append_false); + VirtFsPhys::addDirToSearchPath("../data/test", Append_false); + + file = VirtFsPhys::openRead("test/units.xml"); + REQUIRE(file != nullptr); + VirtFsPhys::close(file); + file = VirtFsPhys::openRead("test/units123.xml"); + REQUIRE(file == nullptr); + file = VirtFsPhys::openRead("tesQ/units.xml"); + REQUIRE(file == nullptr); + file = VirtFsPhys::openRead("units.xml"); + REQUIRE(file != nullptr); + VirtFsPhys::close(file); +// file = VirtFsPhys::openRead("test"); +// REQUIRE(file == nullptr); + file = VirtFsPhys::openRead("testQ"); + REQUIRE(file == nullptr); + + VirtFsPhys::removeDirFromSearchPath("data/test"); + VirtFsPhys::removeDirFromSearchPath("../data/test"); + + file = VirtFsPhys::openRead("test/units.xml"); + REQUIRE(file != nullptr); + VirtFsPhys::close(file); + file = VirtFsPhys::openRead("test/units123.xml"); + REQUIRE(file == nullptr); + file = VirtFsPhys::openRead("tesQ/units.xml"); + REQUIRE(file == nullptr); + file = VirtFsPhys::openRead("units.xml"); + REQUIRE(file == nullptr); +// file = VirtFsPhys::openRead("test"); +// REQUIRE(file == nullptr); + file = VirtFsPhys::openRead("testQ"); + REQUIRE(file == nullptr); + + VirtFsPhys::removeDirFromSearchPath("data"); + VirtFsPhys::removeDirFromSearchPath("../data"); + delete2(logger); +} + +TEST_CASE("VirtFsPhys addZipToSearchPath") +{ + // +++ need implement +} + +TEST_CASE("VirtFsPhys removeZipFromSearchPath") +{ + // +++ need implement +} + +TEST_CASE("VirtFsPhys getRealDir") +{ + VirtFsPhys::initFuncs(); + logger = new Logger(); + REQUIRE(VirtFsPhys::getRealDir(".") == ""); + REQUIRE(VirtFsPhys::getRealDir("..") == ""); + const bool dir1 = VirtFsPhys::addDirToSearchPath("data", Append_false); + REQUIRE((dir1 || VirtFsPhys::addDirToSearchPath( + "../data", Append_false)) == true); + if (dir1 == true) + { + REQUIRE(VirtFsPhys::getRealDir("test") == "data"); + REQUIRE(VirtFsPhys::getRealDir("test/test.txt") == + "data"); + } + else + { + REQUIRE(VirtFsPhys::getRealDir("test") == "../data"); + REQUIRE(VirtFsPhys::getRealDir("test/test.txt") == + "../data"); + } + REQUIRE(VirtFsPhys::getRealDir("zzz") == ""); + + VirtFsPhys::addDirToSearchPath("data/test", Append_false); + VirtFsPhys::addDirToSearchPath("../data/test", Append_false); + if (dir1 == true) + { + REQUIRE(VirtFsPhys::getRealDir("test") == "data"); + REQUIRE(VirtFsPhys::getRealDir("test/test.txt") == + "data"); + REQUIRE(VirtFsPhys::getRealDir("test.txt") == + "data/test"); + } + else + { + REQUIRE(VirtFsPhys::getRealDir("test") == "../data"); + REQUIRE(VirtFsPhys::getRealDir("test/test.txt") == + "../data"); + REQUIRE(VirtFsPhys::getRealDir("test.txt") == + "../data/test"); + } + REQUIRE(VirtFsPhys::getRealDir("zzz") == ""); + + if (dir1 == true) + { + VirtFsPhys::addZipToSearchPath("data/test/test.zip", Append_false); + REQUIRE(VirtFsPhys::getRealDir("dir/brimmedhat.png") == + "data/test/test.zip"); + REQUIRE(VirtFsPhys::getRealDir("hide.png") == "data/test"); + } + else + { + VirtFsPhys::addZipToSearchPath("../data/test/test.zip", Append_false); + REQUIRE(VirtFsPhys::getRealDir("dir/brimmedhat.png") == + "../data/test/test.zip"); + REQUIRE(VirtFsPhys::getRealDir("hide.png") == "../data/test"); + } + + VirtFsPhys::removeDirFromSearchPath("data/test"); + VirtFsPhys::removeDirFromSearchPath("../data/test"); + + if (dir1 == true) + { + REQUIRE(VirtFsPhys::getRealDir("test") == "data"); + REQUIRE(VirtFsPhys::getRealDir("test/test.txt") == + "data"); + REQUIRE(VirtFsPhys::getRealDir("dir/hide.png") == + "data/test/test.zip"); + } + else + { + REQUIRE(VirtFsPhys::getRealDir("test") == "../data"); + REQUIRE(VirtFsPhys::getRealDir("test/test.txt") == + "../data"); + REQUIRE(VirtFsPhys::getRealDir("dir/hide.png") == + "../data/test/test.zip"); + } + REQUIRE(VirtFsPhys::exists("dir/hide.png")); + REQUIRE(VirtFsPhys::getRealDir("zzz") == ""); + + VirtFsPhys::removeDirFromSearchPath("data"); + VirtFsPhys::removeDirFromSearchPath("../data"); + VirtFsPhys::removeZipFromSearchPath("data/test/test.zip"); + VirtFsPhys::removeZipFromSearchPath("../data/test/test.zip"); + delete2(logger); +} + +TEST_CASE("VirtFsPhys permitLinks") +{ + VirtFsPhys::initFuncs(); + logger = new Logger(); + VirtFsPhys::addDirToSearchPath("data", Append_false); + VirtFsPhys::addDirToSearchPath("../data", Append_false); + + const int cnt1 = VirtFsPhys::exists("test/test2.txt") ? 25 : 24; + const int cnt2 = 25; + + StringVect list; + VirtFsPhys::permitLinks(false); + VirtFsPhys::getFiles("test", list); + removeTemp(list); + const size_t sz = list.size(); + REQUIRE(sz == cnt1); + + list.clear(); + VirtFsPhys::permitLinks(true); + VirtFsPhys::getFiles("test", list); + removeTemp(list); + REQUIRE(list.size() == cnt2); + + list.clear(); + VirtFsPhys::permitLinks(false); + VirtFsPhys::getFiles("test", list); + removeTemp(list); + REQUIRE(list.size() == cnt1); + + VirtFsPhys::removeDirFromSearchPath("data"); + VirtFsPhys::removeDirFromSearchPath("../data"); + delete2(logger); +} + +TEST_CASE("VirtFsPhys read") +{ + VirtFsPhys::initFuncs(); + logger = new Logger(); + VirtFsPhys::addDirToSearchPath("data", Append_false); + VirtFsPhys::addDirToSearchPath("../data", Append_false); + + VirtFile *file = VirtFsPhys::openRead("test/test.txt"); + REQUIRE(file != nullptr); + REQUIRE(VirtFsPhys::fileLength(file) == 23); + const int fileSize = VirtFsPhys::fileLength(file); + + void *restrict buffer = calloc(fileSize + 1, 1); + REQUIRE(VirtFsPhys::read(file, buffer, 1, fileSize) == fileSize); + REQUIRE(strcmp(static_cast<char*>(buffer), + "test line 1\ntest line 2") == 0); + REQUIRE(VirtFsPhys::tell(file) == fileSize); + REQUIRE(VirtFsPhys::eof(file) == true); + + free(buffer); + buffer = calloc(fileSize + 1, 1); + REQUIRE(VirtFsPhys::seek(file, 12) != 0); + REQUIRE(VirtFsPhys::eof(file) == false); + REQUIRE(VirtFsPhys::tell(file) == 12); + REQUIRE(VirtFsPhys::read(file, buffer, 1, 11) == 11); + REQUIRE(strcmp(static_cast<char*>(buffer), + "test line 2") == 0); + REQUIRE(VirtFsPhys::eof(file) == true); + + VirtFsPhys::close(file); + free(buffer); + + VirtFsPhys::removeDirFromSearchPath("data"); + VirtFsPhys::removeDirFromSearchPath("../data"); + delete2(logger); +} |