From 6388446b85e1fa5deccc6d5c1683fba88ef53d99 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 27 Feb 2017 18:16:39 +0300 Subject: Add functions pointers into VirtFile. From VirtFs call if possible pointer from VirtFile. --- src/fs/virtfile.cpp | 4 +++- src/fs/virtfile.h | 4 +++- src/fs/virtfs.cpp | 16 +++++++------- src/fs/virtfsdir.cpp | 20 ++++++++++++++++- src/fs/virtfsdir.h | 3 +++ src/fs/virtfsdir_unittest.cc | 15 +++++++++++++ src/fs/virtfsfuncs.h | 50 +++++++++++++++++++++++++++++++++++++++++++ src/fs/virtfsphys.cpp | 25 +++++++++++++++++++--- src/fs/virtfsphys.h | 3 +++ src/fs/virtfsphys_unittest.cc | 11 ++++++++++ src/fs/virtfszip.cpp | 20 ++++++++++++++++- src/fs/virtfszip.h | 3 +++ src/fs/virtfszip_unittest.cc | 12 +++++++++++ 13 files changed, 171 insertions(+), 15 deletions(-) create mode 100644 src/fs/virtfsfuncs.h (limited to 'src/fs') diff --git a/src/fs/virtfile.cpp b/src/fs/virtfile.cpp index 3ed99ca2d..2fe475d4f 100644 --- a/src/fs/virtfile.cpp +++ b/src/fs/virtfile.cpp @@ -21,10 +21,12 @@ #include "fs/virtfile.h" #include "fs/virtfileprivate.h" +#include "fs/virtfsfuncs.h" #include "debug.h" -VirtFile::VirtFile() : +VirtFile::VirtFile(const VirtFsFuncs *restrict const funcs0) : + funcs(funcs0), mPrivate(nullptr) { } diff --git a/src/fs/virtfile.h b/src/fs/virtfile.h index cf7ded1a4..1cb819a6a 100644 --- a/src/fs/virtfile.h +++ b/src/fs/virtfile.h @@ -24,15 +24,17 @@ #include "localconsts.h" struct VirtFilePrivate; +struct VirtFsFuncs; struct VirtFile final { - VirtFile(); + explicit VirtFile(const VirtFsFuncs *restrict const funcs0); A_DELETE_COPY(VirtFile) ~VirtFile(); + const VirtFsFuncs *funcs; VirtFilePrivate *mPrivate; }; diff --git a/src/fs/virtfs.cpp b/src/fs/virtfs.cpp index fa9df5ac2..833d31bd2 100644 --- a/src/fs/virtfs.cpp +++ b/src/fs/virtfs.cpp @@ -22,6 +22,7 @@ #include "fs/virtfsphys.h" #include "fs/virtfile.h" +#include "fs/virtfsfuncs.h" #include "fs/virtlist.h" #include "debug.h" @@ -157,8 +158,7 @@ namespace VirtFs { if (file == nullptr) return 0; - delete file; - return 1; + return file->funcs->close(file); } int64_t read(VirtFile *restrict const file, @@ -166,7 +166,7 @@ namespace VirtFs const uint32_t objSize, const uint32_t objCount) { - return VirtFsPhys::read(file, + return file->funcs->read(file, buffer, objSize, objCount); @@ -177,7 +177,7 @@ namespace VirtFs const uint32_t objSize, const uint32_t objCount) { - return VirtFsPhys::write(file, + return file->funcs->write(file, buffer, objSize, objCount); @@ -185,23 +185,23 @@ namespace VirtFs int64_t fileLength(VirtFile *restrict const file) { - return VirtFsPhys::fileLength(file); + return file->funcs->fileLength(file); } int64_t tell(VirtFile *restrict const file) { - return VirtFsPhys::tell(file); + return file->funcs->tell(file); } int seek(VirtFile *restrict const file, const uint64_t pos) { - return VirtFsPhys::seek(file, + return file->funcs->seek(file, pos); } int eof(VirtFile *restrict const file) { - return VirtFsPhys::eof(file); + return file->funcs->eof(file); } } // namespace VirtFs diff --git a/src/fs/virtfsdir.cpp b/src/fs/virtfsdir.cpp index 249317773..3950aa18c 100644 --- a/src/fs/virtfsdir.cpp +++ b/src/fs/virtfsdir.cpp @@ -27,6 +27,7 @@ #include "fs/virtfs.h" #include "fs/virtfile.h" #include "fs/virtfileprivate.h" +#include "fs/virtfsfuncs.h" #include "fs/virtlist.h" #include "utils/checkutils.h" @@ -50,6 +51,7 @@ namespace std::vector mEntries; std::string mWriteDir; bool mPermitLinks = false; + VirtFsFuncs funcs; } // namespace namespace VirtFsDir @@ -79,7 +81,7 @@ namespace VirtFsDir filename.c_str()); return nullptr; } - VirtFile *restrict const file = new VirtFile; + VirtFile *restrict const file = new VirtFile(&funcs); file->mPrivate = new VirtFilePrivate(fd); return file; @@ -250,6 +252,22 @@ namespace VirtFsDir mEntries.clear(); } + void init() + { + initFuncs(&funcs); + } + + void initFuncs(VirtFsFuncs *restrict const ptr) + { + ptr->close = &VirtFsDir::close; + ptr->read = &VirtFsDir::read; + ptr->write = &VirtFsDir::write; + ptr->fileLength = &VirtFsDir::fileLength; + ptr->tell = &VirtFsDir::tell; + ptr->seek = &VirtFsDir::seek; + ptr->eof = &VirtFsDir::eof; + } + std::string getRealDir(const std::string &restrict filename) { if (checkPath(filename) == false) diff --git a/src/fs/virtfsdir.h b/src/fs/virtfsdir.h index 4fa1c20a5..d090f5366 100644 --- a/src/fs/virtfsdir.h +++ b/src/fs/virtfsdir.h @@ -31,6 +31,7 @@ struct VirtDirEntry; struct VirtFile; +struct VirtFsFuncs; struct VirtList; namespace VirtFsDir @@ -44,6 +45,8 @@ namespace VirtFsDir const SkipError skipError); bool removeFromSearchPath(std::string oldDir); bool removeFromSearchPathSilent(std::string oldDir); + void init(); + void initFuncs(VirtFsFuncs *restrict const ptr); void deinit(); std::vector &getEntries(); bool exists(const std::string &restrict name); diff --git a/src/fs/virtfsdir_unittest.cc b/src/fs/virtfsdir_unittest.cc index aa2b0542b..a005341de 100644 --- a/src/fs/virtfsdir_unittest.cc +++ b/src/fs/virtfsdir_unittest.cc @@ -32,12 +32,15 @@ TEST_CASE("VirtFsDir getEntries") { + VirtFsDir::init(); REQUIRE(VirtFsDir::getEntries().empty()); REQUIRE(VirtFsDir::searchEntryByRoot("test") == nullptr); + VirtFsDir::deinit(); } TEST_CASE("VirtFsDir addToSearchPath") { + VirtFsDir::init(); logger = new Logger(); SECTION("simple 1") { @@ -153,6 +156,7 @@ TEST_CASE("VirtFsDir addToSearchPath") TEST_CASE("VirtFsDir removeFromSearchPath") { + VirtFsDir::init(); logger = new Logger(); SECTION("simple 1") @@ -226,6 +230,7 @@ TEST_CASE("VirtFsDir removeFromSearchPath") TEST_CASE("VirtFsDir exists") { + VirtFsDir::init(); logger = new Logger(); VirtFsDir::addToSearchPathSilent("data", Append_false, @@ -293,6 +298,7 @@ static void removeTemp(StringVect &restrict list) TEST_CASE("VirtFsDir getRealDir") { + VirtFsDir::init(); logger = new Logger(); REQUIRE(VirtFsDir::getRealDir(".") == ""); REQUIRE(VirtFsDir::getRealDir("..") == ""); @@ -376,6 +382,7 @@ static bool inList(VirtList *list, TEST_CASE("VirtFsDir enumerateFiles1") { + VirtFsDir::init(); logger = new Logger; VirtFsDir::addToSearchPathSilent("data", @@ -417,6 +424,7 @@ TEST_CASE("VirtFsDir enumerateFiles1") TEST_CASE("VirtFsDir enumerateFiles2") { + VirtFsDir::init(); logger = new Logger; VirtFsDir::addToSearchPathSilent("data/test/dir1", @@ -440,6 +448,7 @@ TEST_CASE("VirtFsDir enumerateFiles2") TEST_CASE("VirtFsDir enumerateFiles3") { + VirtFsDir::init(); logger = new Logger; VirtFsDir::addToSearchPathSilent("data/test/dir1", @@ -469,6 +478,7 @@ TEST_CASE("VirtFsDir enumerateFiles3") TEST_CASE("VirtFsDir isDirectory") { + VirtFsDir::init(); logger = new Logger(); VirtFsDir::addToSearchPathSilent("data", Append_false, @@ -536,6 +546,7 @@ TEST_CASE("VirtFsDir isDirectory") TEST_CASE("VirtFsDir openRead") { + VirtFsDir::init(); logger = new Logger(); VirtFsDir::addToSearchPathSilent("data", Append_false, @@ -602,6 +613,7 @@ TEST_CASE("VirtFsDir openRead") TEST_CASE("VirtFsDir permitLinks") { + VirtFsDir::init(); logger = new Logger(); VirtFsDir::addToSearchPathSilent("data", Append_false, @@ -634,11 +646,13 @@ TEST_CASE("VirtFsDir permitLinks") VirtFsDir::removeFromSearchPathSilent("data"); VirtFsDir::removeFromSearchPathSilent("../data"); + VirtFsDir::deinit(); delete2(logger); } TEST_CASE("VirtFsDir read") { + VirtFsDir::init(); logger = new Logger(); VirtFsDir::addToSearchPathSilent("data", Append_false, @@ -674,5 +688,6 @@ TEST_CASE("VirtFsDir read") VirtFsDir::removeFromSearchPathSilent("data"); VirtFsDir::removeFromSearchPathSilent("../data"); + VirtFsDir::deinit(); delete2(logger); } diff --git a/src/fs/virtfsfuncs.h b/src/fs/virtfsfuncs.h new file mode 100644 index 000000000..1b17ac5db --- /dev/null +++ b/src/fs/virtfsfuncs.h @@ -0,0 +1,50 @@ +/* + * 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 . + */ + +#ifndef UTILS_VIRTFSFUNCS_H +#define UTILS_VIRTFSFUNCS_H + +#include "enums/simpletypes/append.h" + +#include "localconsts.h" + +#include + +struct VirtFile; + +struct VirtFsFuncs +{ + int (*close) (VirtFile *restrict const file); + int64_t (*read) (VirtFile *restrict const file, + 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); + 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); +}; + +#endif // UTILS_VIRTFSFUNCS_H diff --git a/src/fs/virtfsphys.cpp b/src/fs/virtfsphys.cpp index 16b2c40df..d5cb1c1a2 100644 --- a/src/fs/virtfsphys.cpp +++ b/src/fs/virtfsphys.cpp @@ -22,6 +22,7 @@ #include "fs/virtfile.h" #include "fs/virtfileprivate.h" +#include "fs/virtfsfuncs.h" #include "fs/virtlist.h" #include "utils/checkutils.h" @@ -38,6 +39,7 @@ namespace { const char *dirSeparator = nullptr; + VirtFsFuncs funcs; } // namespace namespace VirtFsPhys @@ -63,6 +65,23 @@ namespace VirtFsPhys } updateDirSeparator(); atexit(reinterpret_cast(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() @@ -126,7 +145,7 @@ namespace VirtFsPhys filename.c_str()); if (!handle) return nullptr; - VirtFile *restrict const file = new VirtFile; + VirtFile *restrict const file = new VirtFile(&funcs); file->mPrivate = new VirtFilePrivate(handle); return file; } @@ -137,7 +156,7 @@ namespace VirtFsPhys filename.c_str()); if (!handle) return nullptr; - VirtFile *restrict const file = new VirtFile; + VirtFile *restrict const file = new VirtFile(&funcs); file->mPrivate = new VirtFilePrivate(handle); return file; } @@ -148,7 +167,7 @@ namespace VirtFsPhys filename.c_str()); if (!handle) return nullptr; - VirtFile *restrict const file = new VirtFile; + VirtFile *restrict const file = new VirtFile(&funcs); file->mPrivate = new VirtFilePrivate(handle); return file; } diff --git a/src/fs/virtfsphys.h b/src/fs/virtfsphys.h index 99c3e3e0c..743530c6c 100644 --- a/src/fs/virtfsphys.h +++ b/src/fs/virtfsphys.h @@ -28,11 +28,14 @@ #include 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(); diff --git a/src/fs/virtfsphys_unittest.cc b/src/fs/virtfsphys_unittest.cc index efb37e2d7..93f86db64 100644 --- a/src/fs/virtfsphys_unittest.cc +++ b/src/fs/virtfsphys_unittest.cc @@ -32,6 +32,7 @@ TEST_CASE("VirtFsPhys dirSeparator") { + VirtFsPhys::initFuncs(); REQUIRE(VirtFs::getDirSeparator() != nullptr); REQUIRE(VirtFsPhys::getDirSeparator() == std::string(VirtFs::getDirSeparator())); @@ -43,16 +44,19 @@ TEST_CASE("VirtFsPhys dirSeparator") TEST_CASE("VirtFsPhys getBaseDir") { + VirtFsPhys::initFuncs(); REQUIRE(VirtFsPhys::getBaseDir() != nullptr); } TEST_CASE("VirtFsPhys getUserDir") { + VirtFsPhys::initFuncs(); REQUIRE(VirtFsPhys::getUserDir() != nullptr); } TEST_CASE("VirtFsPhys exists") { + VirtFsPhys::initFuncs(); logger = new Logger(); VirtFsPhys::addDirToSearchPath("data", Append_false); VirtFsPhys::addDirToSearchPath("../data", Append_false); @@ -111,6 +115,7 @@ static void removeTemp(StringVect &restrict list) TEST_CASE("VirtFsPhys enumerateFiles1") { + VirtFsPhys::initFuncs(); logger = new Logger; VirtFsPhys::addDirToSearchPath("data", Append_false); @@ -147,6 +152,7 @@ TEST_CASE("VirtFsPhys enumerateFiles1") TEST_CASE("VirtFsPhys enumerateFiles2") { + VirtFsPhys::initFuncs(); logger = new Logger; VirtFsPhys::addDirToSearchPath("data/test/dir1", @@ -168,6 +174,7 @@ TEST_CASE("VirtFsPhys enumerateFiles2") TEST_CASE("VirtFsPhys isDirectory") { + VirtFsPhys::initFuncs(); logger = new Logger(); VirtFsPhys::addDirToSearchPath("data", Append_false); VirtFsPhys::addDirToSearchPath("../data", Append_false); @@ -226,6 +233,7 @@ TEST_CASE("VirtFsPhys isDirectory") TEST_CASE("VirtFsPhys openRead") { + VirtFsPhys::initFuncs(); logger = new Logger(); VirtFsPhys::addDirToSearchPath("data", Append_false); VirtFsPhys::addDirToSearchPath("../data", Append_false); @@ -298,6 +306,7 @@ TEST_CASE("VirtFsPhys removeZipFromSearchPath") TEST_CASE("VirtFsPhys getRealDir") { + VirtFsPhys::initFuncs(); logger = new Logger(); REQUIRE(VirtFsPhys::getRealDir(".") == ""); REQUIRE(VirtFsPhys::getRealDir("..") == ""); @@ -382,6 +391,7 @@ TEST_CASE("VirtFsPhys getRealDir") TEST_CASE("VirtFsPhys permitLinks") { + VirtFsPhys::initFuncs(); logger = new Logger(); VirtFsPhys::addDirToSearchPath("data", Append_false); VirtFsPhys::addDirToSearchPath("../data", Append_false); @@ -415,6 +425,7 @@ TEST_CASE("VirtFsPhys permitLinks") TEST_CASE("VirtFsPhys read") { + VirtFsPhys::initFuncs(); logger = new Logger(); VirtFsPhys::addDirToSearchPath("data", Append_false); VirtFsPhys::addDirToSearchPath("../data", Append_false); diff --git a/src/fs/virtfszip.cpp b/src/fs/virtfszip.cpp index fe75c0192..fa47892b5 100644 --- a/src/fs/virtfszip.cpp +++ b/src/fs/virtfszip.cpp @@ -24,6 +24,7 @@ #include "fs/paths.h" #include "fs/virtfile.h" #include "fs/virtfileprivate.h" +#include "fs/virtfsfuncs.h" #include "fs/virtlist.h" #include "fs/virtzipentry.h" #include "fs/zip.h" @@ -40,6 +41,7 @@ extern const char *dirSeparator; namespace { std::vector mEntries; + VirtFsFuncs funcs; } // namespace namespace VirtFsZip @@ -209,6 +211,22 @@ namespace VirtFsZip mEntries.clear(); } + void init() + { + initFuncs(&funcs); + } + + void initFuncs(VirtFsFuncs *restrict const ptr) + { + ptr->close = &VirtFsZip::close; + ptr->read = &VirtFsZip::read; + ptr->write = &VirtFsZip::write; + ptr->fileLength = &VirtFsZip::fileLength; + ptr->tell = &VirtFsZip::tell; + ptr->seek = &VirtFsZip::seek; + ptr->eof = &VirtFsZip::eof; + } + std::string getRealDir(const std::string &restrict filename) { if (checkPath(filename) == false) @@ -337,7 +355,7 @@ namespace VirtFsZip uint8_t *restrict const buf = Zip::readFile(header); if (buf == nullptr) return nullptr; - VirtFile *restrict const file = new VirtFile; + VirtFile *restrict const file = new VirtFile(&funcs); file->mPrivate = new VirtFilePrivate(buf, header->uncompressSize); return file; diff --git a/src/fs/virtfszip.h b/src/fs/virtfszip.h index 9ccd59ed5..81feb3693 100644 --- a/src/fs/virtfszip.h +++ b/src/fs/virtfszip.h @@ -31,6 +31,7 @@ struct VirtFile; struct VirtList; +struct VirtFsFuncs; struct VirtZipEntry; struct ZipLocalHeader; @@ -44,6 +45,8 @@ namespace VirtFsZip const Append append); bool removeFromSearchPath(std::string oldDir); bool removeFromSearchPathSilent(std::string oldDir); + void init(); + void initFuncs(VirtFsFuncs *restrict const ptr); void deinit(); std::vector &getEntries(); bool exists(const std::string &restrict name); diff --git a/src/fs/virtfszip_unittest.cc b/src/fs/virtfszip_unittest.cc index 3988ffc0c..05167a358 100644 --- a/src/fs/virtfszip_unittest.cc +++ b/src/fs/virtfszip_unittest.cc @@ -32,12 +32,15 @@ TEST_CASE("VirtFsZip getEntries") { + VirtFsZip::init(); REQUIRE(VirtFsZip::getEntries().empty()); REQUIRE(VirtFsZip::searchEntryByArchive("test.zip") == nullptr); + VirtFsZip::deinit(); } TEST_CASE("VirtFsZip addToSearchPath") { + VirtFsZip::init(); logger = new Logger(); std::string name("data/test/test.zip"); std::string prefix("data/test/"); @@ -165,6 +168,7 @@ TEST_CASE("VirtFsZip addToSearchPath") TEST_CASE("VirtFsZip removeFromSearchPath") { + VirtFsZip::init(); logger = new Logger(); std::string name("data/test/test.zip"); std::string prefix("data/test/"); @@ -238,6 +242,7 @@ TEST_CASE("VirtFsZip removeFromSearchPath") TEST_CASE("VirtFsZip exists") { + VirtFsZip::init(); logger = new Logger(); VirtFsZip::addToSearchPathSilent("data/test/test2.zip", Append_false); @@ -281,6 +286,7 @@ TEST_CASE("VirtFsZip exists") TEST_CASE("VirtFsZip getRealDir") { + VirtFsZip::init(); logger = new Logger(); std::string name("data/test/test.zip"); std::string prefix("data/test/"); @@ -332,6 +338,7 @@ static bool inList(VirtList *list, TEST_CASE("VirtFsZip enumerateFiles1") { + VirtFsZip::init(); logger = new Logger; std::string name("data/test/test.zip"); std::string prefix("data/test/"); @@ -356,6 +363,7 @@ TEST_CASE("VirtFsZip enumerateFiles1") TEST_CASE("VirtFsZip enumerateFiles2") { + VirtFsZip::init(); logger = new Logger; std::string name("data/test/test.zip"); std::string prefix("data/test/"); @@ -391,6 +399,7 @@ TEST_CASE("VirtFsZip enumerateFiles2") TEST_CASE("VirtFsZip isDirectory") { + VirtFsZip::init(); logger = new Logger(); std::string name("data/test/test.zip"); std::string prefix("data/test/"); @@ -476,6 +485,7 @@ TEST_CASE("VirtFsZip isDirectory") TEST_CASE("VirtFsZip openRead") { + VirtFsZip::init(); logger = new Logger(); std::string name("data/test/test.zip"); std::string prefix("data/test/"); @@ -543,6 +553,7 @@ TEST_CASE("VirtFsZip openRead") TEST_CASE("VirtFsZip read") { + VirtFsZip::init(); logger = new Logger(); std::string name("data/test/test.zip"); std::string prefix("data/test/"); @@ -667,5 +678,6 @@ TEST_CASE("VirtFsZip read") VirtFsZip::close(file); free(buffer); VirtFsZip::removeFromSearchPathSilent(prefix + "test2.zip"); + VirtFsZip::deinit(); delete2(logger); } -- cgit v1.2.3-70-g09d2