From 4d3c700bf736def3c55f7e03c175e2e43ed3db02 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Fri, 10 Feb 2017 21:57:08 +0300 Subject: Rename physfsrwops into virtfsrwops. --- src/CMakeLists.txt | 8 +- src/Makefile.am | 4 +- src/debug.h | 7 +- src/gui/fonts/font.cpp | 2 +- src/integrity_unittest.cc | 10 +- src/maingui.cpp | 4 +- src/resources/atlas/atlasmanager.cpp | 4 +- src/resources/loaders/imageloader.cpp | 4 +- src/resources/loaders/musicloader.cpp | 4 +- src/resources/loaders/soundloader.cpp | 4 +- src/resources/resourcemanager/resourcemanager.cpp | 2 +- src/test/testlauncher.cpp | 6 +- src/utils/physfscheckutils.cpp | 4 +- src/utils/physfsrwops.cpp | 316 --------------------- src/utils/physfsrwops.h | 86 ------ src/utils/virtfsrwops.cpp | 317 ++++++++++++++++++++++ src/utils/virtfsrwops.h | 45 +++ 17 files changed, 391 insertions(+), 436 deletions(-) delete mode 100644 src/utils/physfsrwops.cpp delete mode 100644 src/utils/physfsrwops.h create mode 100644 src/utils/virtfsrwops.cpp create mode 100644 src/utils/virtfsrwops.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1e14b48de..1baa24081 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -889,8 +889,8 @@ SET(SRCS utils/physfscheckutils.cpp utils/physfscheckutils.h utils/physfsmemoryobject.h - utils/physfsrwops.cpp - utils/physfsrwops.h + utils/virtfsrwops.cpp + utils/virtfsrwops.h utils/virtfs.cpp utils/virtfs.h utils/process.cpp @@ -1767,8 +1767,8 @@ SET(DYE_CMD_SRCS utils/paths.h utils/perfomance.cpp utils/perfomance.h - utils/physfsrwops.cpp - utils/physfsrwops.h + utils/virtfsrwops.cpp + utils/virtfsrwops.h utils/virtfs.cpp utils/virtfs.h utils/sdl2helper.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 35f331b12..2eea657a5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -549,8 +549,8 @@ BASE_SRC += events/actionevent.h \ utils/physfscheckutils.cpp \ utils/physfscheckutils.h \ utils/physfsmemoryobject.h \ - utils/physfsrwops.cpp \ - utils/physfsrwops.h \ + utils/virtfsrwops.cpp \ + utils/virtfsrwops.h \ utils/virtfs.cpp \ utils/virtfs.h \ utils/process.cpp \ diff --git a/src/debug.h b/src/debug.h index 9ab7a8874..3faf63cde 100644 --- a/src/debug.h +++ b/src/debug.h @@ -65,12 +65,7 @@ #ifdef DEBUG_PHYSFS - -#define MPHYSFSRWOPS_openRead(name) \ - FakePHYSFSRWOPS_openRead(name, __FILE__, __LINE__) - +// +++ need move this into VirtFs itself #else // DEBUG_PHYSFS -#define MPHYSFSRWOPS_openRead(name) PHYSFSRWOPS_openRead(name) - #endif // DEBUG_PHYSFS diff --git a/src/gui/fonts/font.cpp b/src/gui/fonts/font.cpp index cca641d03..73b91ad4c 100644 --- a/src/gui/fonts/font.cpp +++ b/src/gui/fonts/font.cpp @@ -157,7 +157,7 @@ TTF_Font *Font::openFont(const char *const name, const int size) { // disabled for now because some systems like gentoo can't use it // #ifdef USE_SDL2 -// SDL_RWops *const rw = MPHYSFSRWOPS_openRead(name); +// SDL_RWops *const rw = VirtFs::RWopsOpenRead(name); // if (!rw) // return nullptr; // return TTF_OpenFontIndexRW(rw, 1, size, 0); diff --git a/src/integrity_unittest.cc b/src/integrity_unittest.cc index 86317dc40..a907ca5fb 100644 --- a/src/integrity_unittest.cc +++ b/src/integrity_unittest.cc @@ -39,7 +39,7 @@ #include "resources/resourcemanager/resourcemanager.h" #include "utils/env.h" -#include "utils/physfsrwops.h" +#include "utils/virtfsrwops.h" #include @@ -240,7 +240,7 @@ TEST_CASE("integrity tests", "integrity") resourceManager->addToSearchPath("data/test/test.zip", Append_false); resourceManager->addToSearchPath("../data/test/test.zip", Append_false); - SDL_RWops *const rw = PHYSFSRWOPS_openRead(name1); + SDL_RWops *const rw = VirtFs::RWopsOpenRead(name1); if (!rw) logger->log("Physfs error: %s", VirtFs::getLastError()); resourceManager->removeFromSearchPath("data/test/test.zip"); @@ -403,7 +403,7 @@ TEST_CASE("integrity tests", "integrity") resourceManager->addToSearchPath("data/test/test.zip", Append_false); resourceManager->addToSearchPath("../data/test/test.zip", Append_false); - SDL_RWops *const rw = PHYSFSRWOPS_openRead(name1); + SDL_RWops *const rw = VirtFs::RWopsOpenRead(name1); if (!rw) logger->log("Physfs error: %s", VirtFs::getLastError()); REQUIRE(rw != nullptr); @@ -438,7 +438,7 @@ TEST_CASE("integrity tests", "integrity") resourceManager->addToSearchPath("data/test/test.zip", Append_false); resourceManager->addToSearchPath("../data/test/test.zip", Append_false); - SDL_RWops *const rw = PHYSFSRWOPS_openRead(name1); + SDL_RWops *const rw = VirtFs::RWopsOpenRead(name1); if (!rw) logger->log("Physfs error: %s", VirtFs::getLastError()); REQUIRE(rw != nullptr); @@ -460,7 +460,7 @@ TEST_CASE("integrity tests", "integrity") resourceManager->addToSearchPath("data/test/test.zip", Append_false); resourceManager->addToSearchPath("../data/test/test.zip", Append_false); - SDL_RWops *const rw = PHYSFSRWOPS_openRead(name1); + SDL_RWops *const rw = VirtFs::RWopsOpenRead(name1); if (!rw) logger->log("Physfs error: %s", VirtFs::getLastError()); REQUIRE(rw != nullptr); diff --git a/src/maingui.cpp b/src/maingui.cpp index 6f8de4083..b2a25b48e 100644 --- a/src/maingui.cpp +++ b/src/maingui.cpp @@ -32,7 +32,7 @@ #include "utils/paths.h" #endif // ANDROID #include "utils/physfscheckutils.h" -#include "utils/physfsrwops.h" +#include "utils/virtfsrwops.h" #include "utils/process.h" #include "utils/xml.h" @@ -132,7 +132,7 @@ int mainGui(int argc, char *argv[]) #endif // SDL_IMAGE_VERSION_ATLEAST(1, 2, 11) #ifdef DUMP_LEAKED_RESOURCES - reportRWops(); + VirtFs::reportRWops(); #endif // DUMP_LEAKED_RESOURCES #ifdef DEBUG_PHYSFS reportPhysfsLeaks(); diff --git a/src/resources/atlas/atlasmanager.cpp b/src/resources/atlas/atlasmanager.cpp index 7299e76d3..e3c6e685b 100644 --- a/src/resources/atlas/atlasmanager.cpp +++ b/src/resources/atlas/atlasmanager.cpp @@ -30,7 +30,7 @@ #include "utils/mathutils.h" #include "utils/physfscheckutils.h" -#include "utils/physfsrwops.h" +#include "utils/virtfsrwops.h" #include "utils/sdlcheckutils.h" #include "resources/openglimagehelper.h" @@ -149,7 +149,7 @@ void AtlasManager::loadImages(const StringVect &files, path = path.substr(0, p); } - SDL_RWops *const rw = MPHYSFSRWOPS_openRead(path.c_str()); + SDL_RWops *const rw = VirtFs::RWopsOpenRead(path.c_str()); if (rw) { Image *const image = d ? surfaceImageHelper->load(rw, *d) diff --git a/src/resources/loaders/imageloader.cpp b/src/resources/loaders/imageloader.cpp index 4fada1f44..54f987bab 100644 --- a/src/resources/loaders/imageloader.cpp +++ b/src/resources/loaders/imageloader.cpp @@ -31,7 +31,7 @@ #include "resources/dye/dye.h" #include "utils/checkutils.h" -#include "utils/physfsrwops.h" +#include "utils/virtfsrwops.h" #include "debug.h" @@ -62,7 +62,7 @@ namespace d = new Dye(path1.substr(p + 1)); path1 = path1.substr(0, p); } - SDL_RWops *const rw = MPHYSFSRWOPS_openRead(path1.c_str()); + SDL_RWops *const rw = VirtFs::RWopsOpenRead(path1.c_str()); if (!rw) { delete d; diff --git a/src/resources/loaders/musicloader.cpp b/src/resources/loaders/musicloader.cpp index 7b0cda647..c22843d39 100644 --- a/src/resources/loaders/musicloader.cpp +++ b/src/resources/loaders/musicloader.cpp @@ -27,7 +27,7 @@ #include "resources/resourcemanager/resourcemanager.h" #include "utils/checkutils.h" -#include "utils/physfsrwops.h" +#include "utils/virtfsrwops.h" #include "debug.h" @@ -45,7 +45,7 @@ namespace return nullptr; const ResourceLoader *const rl = static_cast(v); - SDL_RWops *const rw = MPHYSFSRWOPS_openRead(rl->path.c_str()); + SDL_RWops *const rw = VirtFs::RWopsOpenRead(rl->path.c_str()); if (!rw) { reportAlways("Physfs error: %s", VirtFs::getLastError()); diff --git a/src/resources/loaders/soundloader.cpp b/src/resources/loaders/soundloader.cpp index 569d2dfbe..71ceca8bd 100644 --- a/src/resources/loaders/soundloader.cpp +++ b/src/resources/loaders/soundloader.cpp @@ -27,7 +27,7 @@ #include "resources/resourcemanager/resourcemanager.h" #include "utils/checkutils.h" -#include "utils/physfsrwops.h" +#include "utils/virtfsrwops.h" #include "debug.h" @@ -45,7 +45,7 @@ namespace return nullptr; const ResourceLoader *const rl = static_cast(v); - SDL_RWops *const rw = MPHYSFSRWOPS_openRead(rl->path.c_str()); + SDL_RWops *const rw = VirtFs::RWopsOpenRead(rl->path.c_str()); if (!rw) { reportAlways("Physfs error: %s", VirtFs::getLastError()); diff --git a/src/resources/resourcemanager/resourcemanager.cpp b/src/resources/resourcemanager/resourcemanager.cpp index 8b51b1ec2..2a2fa42e2 100644 --- a/src/resources/resourcemanager/resourcemanager.cpp +++ b/src/resources/resourcemanager/resourcemanager.cpp @@ -36,7 +36,7 @@ #include "utils/checkutils.h" #include "utils/delete2.h" -#include "utils/physfsrwops.h" +#include "utils/virtfsrwops.h" #ifndef USE_OPENGL #include diff --git a/src/test/testlauncher.cpp b/src/test/testlauncher.cpp index 767082bbd..acd51413f 100644 --- a/src/test/testlauncher.cpp +++ b/src/test/testlauncher.cpp @@ -32,7 +32,7 @@ #include "gui/fonts/font.h" #include "utils/physfscheckutils.h" -#include "utils/physfsrwops.h" +#include "utils/virtfsrwops.h" #include "render/graphics.h" @@ -433,7 +433,7 @@ PRAGMA45(GCC diagnostic pop) int TestLauncher::testDye() { - SDL_RWops *rw = MPHYSFSRWOPS_openRead( + SDL_RWops *rw = VirtFs::RWopsOpenRead( "graphics/sprites/arrow_up.png"); Dye *d = nullptr; @@ -456,7 +456,7 @@ int TestLauncher::testDye() settings.tempDir + "/testimage2.png"); } - rw = MPHYSFSRWOPS_openRead( + rw = VirtFs::RWopsOpenRead( "graphics/sprites/arrow_up.png"); d = new Dye("S:#0000ff,00ff00,5c5cff,ff0000"); image = surfaceImageHelper->load(rw, *d); diff --git a/src/utils/physfscheckutils.cpp b/src/utils/physfscheckutils.cpp index 0dc3033eb..3c0382f0c 100644 --- a/src/utils/physfscheckutils.cpp +++ b/src/utils/physfscheckutils.cpp @@ -27,7 +27,7 @@ #include "utils/stringutils.h" #include "utils/physfsmemoryobject.h" -#include "utils/physfsrwops.h" +#include "utils/virtfsrwops.h" #include @@ -75,7 +75,7 @@ SDL_RWops *FakePHYSFSRWOPS_openRead(const char *restrict const name, const char *restrict const file, const unsigned line) { - return addRWops(PHYSFSRWOPS_openRead(name), name, file, line); + return addRWops(VirtFs::RWopsOpenRead(name), name, file, line); } void FakePhysFSClose(SDL_RWops *const rwops) diff --git a/src/utils/physfsrwops.cpp b/src/utils/physfsrwops.cpp deleted file mode 100644 index e642f71aa..000000000 --- a/src/utils/physfsrwops.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/* - * This code provides a glue layer between PhysicsFS and Simple Directmedia - * Layer's (SDL) RWops i/o abstraction. - * - * License: this code is public domain. I make no warranty that it is useful, - * correct, harmless, or environmentally safe. - * - * This particular file may be used however you like, including copying it - * verbatim into a closed-source project, exploiting it commercially, and - * removing any trace of my name from the source (although I hope you won't - * do that). I welcome enhancements and corrections to this file, but I do - * not require you to send me patches if you make changes. This code has - * NO WARRANTY. - * - * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license. - * Please see LICENSE.txt in the root of the source tree. - * - * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/ - * - * This file was written by Ryan C. Gordon. (icculus@icculus.org). - * - * Copyright (C) 2012-2017 The ManaPlus Developers - */ - -#include "utils/physfsrwops.h" - -#include "logger.h" - -#include "utils/fuzzer.h" -#include "utils/physfscheckutils.h" - -#include "debug.h" - -#ifdef USE_SDL2 -#define PHYSFSINT int64_t -#define PHYSFSSIZE size_t -#else // USE_SDL2 -#define PHYSFSINT int32_t -#define PHYSFSSIZE int -#endif // USE_SDL2 - -#ifdef DUMP_LEAKED_RESOURCES -static int openedRWops = 0; -#endif // DUMP_LEAKED_RESOURCES - -static PHYSFSINT physfsrwops_seek(SDL_RWops *const rw, const PHYSFSINT offset, - const int whence) -{ - if (!rw) - return -1; - PHYSFS_file *const handle = static_cast( - rw->hidden.unknown.data1); - PHYSFSINT pos = 0; - - if (whence == SEEK_SET) - { - pos = offset; - } /* if */ - else if (whence == SEEK_CUR) - { - const int64_t current = VirtFs::tell(handle); - if (current == -1) - { - logger->assertLog( - "physfsrwops_seek: Can't find position in file: %s", - VirtFs::getLastError()); - return -1; - } /* if */ - - pos = CAST_S32(current); - if (static_cast(pos) != current) - { - logger->assertLog("physfsrwops_seek: " - "Can't fit current file position in an int!"); - return -1; - } /* if */ - - if (offset == 0) /* this is a "tell" call. We're done. */ - return pos; - - pos += offset; - } /* else if */ - else if (whence == SEEK_END) - { - const int64_t len = VirtFs::fileLength(handle); - if (len == -1) - { - logger->assertLog("physfsrwops_seek:Can't find end of file: %s", - VirtFs::getLastError()); - return -1; - } /* if */ - - pos = static_cast(len); - if (static_cast(pos) != len) - { - logger->assertLog("physfsrwops_seek: " - "Can't fit end-of-file position in an int!"); - return -1; - } /* if */ - - pos += offset; - } /* else if */ - else - { - logger->assertLog("physfsrwops_seek: Invalid 'whence' parameter."); - return -1; - } /* else */ - - if (pos < 0) - { - logger->assertLog("physfsrwops_seek: " - "Attempt to seek past start of file."); - return -1; - } /* if */ - - if (!VirtFs::seek(handle, static_cast(pos))) - { - logger->assertLog("physfsrwops_seek: seek error: %s", - VirtFs::getLastError()); - return -1; - } /* if */ - - return pos; -} /* physfsrwops_seek */ - -static PHYSFSSIZE physfsrwops_read(SDL_RWops *const rw, - void *ptr, - const PHYSFSSIZE size, - const PHYSFSSIZE maxnum) -{ - if (!rw) - return 0; - PHYSFS_file *const handle = static_cast( - rw->hidden.unknown.data1); - const int64_t rc = VirtFs::read(handle, ptr, - CAST_U32(size), - CAST_U32(maxnum)); - if (rc != static_cast(maxnum)) - { - if (!VirtFs::eof(handle)) /* not EOF? Must be an error. */ - { - logger->assertLog("physfsrwops_seek: read error: %s", - PHYSFS_getLastError()); - } - } /* if */ - - return CAST_S32(rc); -} /* physfsrwops_read */ - -static PHYSFSSIZE physfsrwops_write(SDL_RWops *const rw, const void *ptr, - const PHYSFSSIZE size, - const PHYSFSSIZE num) -{ - if (!rw) - return 0; - PHYSFS_file *const handle = static_cast( - rw->hidden.unknown.data1); - const int64_t rc = VirtFs::write(handle, ptr, - CAST_U32(size), - CAST_U32(num)); - if (rc != static_cast(num)) - { - logger->assertLog("physfsrwops_seek: write error: %s", - PHYSFS_getLastError()); - } - - return CAST_S32(rc); -} /* physfsrwops_write */ - -static int physfsrwops_close(SDL_RWops *const rw) -{ - if (!rw) - return 0; - PHYSFS_file *const handle = static_cast( - rw->hidden.unknown.data1); - if (!VirtFs::close(handle)) - { - logger->assertLog("physfsrwops_seek: close error: %s", - VirtFs::getLastError()); - return -1; - } /* if */ - - SDL_FreeRW(rw); -#ifdef DUMP_LEAKED_RESOURCES - if (openedRWops <= 0) - logger->assertLog("physfsrwops_seek: closing already closed RWops"); - openedRWops --; -#endif // DUMP_LEAKED_RESOURCES -#ifdef DEBUG_PHYSFS - FakePhysFSClose(rw); -#endif // DEBUG_PHYSFS - - return 0; -} /* physfsrwops_close */ - -#ifdef USE_SDL2 -static PHYSFSINT physfsrwops_size(SDL_RWops *const rw) -{ - PHYSFS_file *const handle = static_cast( - rw->hidden.unknown.data1); - return VirtFs::fileLength(handle); -} /* physfsrwops_size */ -#endif // USE_SDL2 - -static SDL_RWops *create_rwops(PHYSFS_file *const handle) -{ - SDL_RWops *retval = nullptr; - - if (!handle) - { - logger->assertLog("physfsrwops_seek: create rwops error: %s", - VirtFs::getLastError()); - } - else - { - retval = SDL_AllocRW(); - if (retval) - { -#ifdef USE_SDL2 - retval->size = &physfsrwops_size; -#endif // USE_SDL2 - - retval->seek = &physfsrwops_seek; - retval->read = &physfsrwops_read; - retval->write = &physfsrwops_write; - retval->close = &physfsrwops_close; - retval->hidden.unknown.data1 = handle; - } /* if */ -#ifdef DUMP_LEAKED_RESOURCES - openedRWops ++; -#endif // DUMP_LEAKED_RESOURCES - } /* else */ - - return retval; -} /* create_rwops */ - -SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *const handle) -{ - SDL_RWops *retval = nullptr; - if (!handle) - { - logger->assertLog("physfsrwops_seek: NULL pointer passed to " - "PHYSFSRWOPS_makeRWops()."); - } - else - { - retval = create_rwops(handle); - } - - return retval; -} /* PHYSFSRWOPS_makeRWops */ - -#ifdef __APPLE__ -static bool checkFilePath(const char *const fname) -{ - if (!fname || !*fname) - return false; - if (!VirtFs::exists(fname) || VirtFs::isDirectory(fname)) - return false; - return true; -} -#endif // __APPLE__ - -SDL_RWops *PHYSFSRWOPS_openRead(const char *const fname) -{ - BLOCK_START("PHYSFSRWOPS_openRead") -#ifdef __APPLE__ - if (!checkFilePath(fname)) - return nullptr; -#endif // __APPLE__ -#ifdef USE_FUZZER - if (Fuzzer::conditionTerminate(fname)) - return nullptr; -#endif // USE_FUZZER -#ifdef USE_PROFILER - SDL_RWops *const ret = create_rwops(VirtFs::openRead(fname)); - BLOCK_END("PHYSFSRWOPS_openRead") - return ret; -#else // USE_PROFILER - - return create_rwops(VirtFs::openRead(fname)); -#endif // USE_PROFILER -} /* PHYSFSRWOPS_openRead */ - -SDL_RWops *PHYSFSRWOPS_openWrite(const char *const fname) -{ -#ifdef __APPLE__ - if (!checkFilePath(fname)) - return nullptr; -#endif // __APPLE__ - - return create_rwops(VirtFs::openWrite(fname)); -} /* PHYSFSRWOPS_openWrite */ - -SDL_RWops *PHYSFSRWOPS_openAppend(const char *const fname) -{ -#ifdef __APPLE__ - if (!checkFilePath(fname)) - return nullptr; -#endif // __APPLE__ - - return create_rwops(VirtFs::openAppend(fname)); -} /* PHYSFSRWOPS_openAppend */ - -#ifdef DUMP_LEAKED_RESOURCES -void reportRWops() -{ - if (openedRWops) - { - logger->assertLog("physfsrwops_seek: leaking RWops: %d", - openedRWops); - } -} -#endif // DUMP_LEAKED_RESOURCES - -/* end of physfsrwops.c ... */ diff --git a/src/utils/physfsrwops.h b/src/utils/physfsrwops.h deleted file mode 100644 index 98608458c..000000000 --- a/src/utils/physfsrwops.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This code provides a glue layer between PhysicsFS and Simple Directmedia - * Layer's (SDL) RWops i/o abstraction. - * - * License: this code is public domain. I make no warranty that it is useful, - * correct, harmless, or environmentally safe. - * - * This particular file may be used however you like, including copying it - * verbatim into a closed-source project, exploiting it commercially, and - * removing any trace of my name from the source (although I hope you won't - * do that). I welcome enhancements and corrections to this file, but I do - * not require you to send me patches if you make changes. This code has - * NO WARRANTY. - * - * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license. - * Please see LICENSE.txt in the root of the source tree. - * - * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/ - * - * This file was written by Ryan C. Gordon. (icculus@icculus.org). - * - * Copyright (C) 2012-2017 The ManaPlus Developers - */ - -#ifndef UTILS_PHYSFSRWOPS_H -#define UTILS_PHYSFSRWOPS_H - -#include "localconsts.h" - -#include - -#include "utils/virtfs.h" - -/** - * Open a platform-independent filename for reading, and make it accessible - * via an SDL_RWops structure. The file will be closed in PhysicsFS when the - * RWops is closed. PhysicsFS should be configured to your liking before - * opening files through this method. - * - * @param fname File to open in platform-independent notation. - * @return A valid SDL_RWops structure on success, NULL on error. Specifics - * of the error can be gleaned from PHYSFS_getLastError(). - */ -SDL_RWops *PHYSFSRWOPS_openRead(const char *const fname) A_WARN_UNUSED; - -/** - * Open a platform-independent filename for writing, and make it accessible - * via an SDL_RWops structure. The file will be closed in PhysicsFS when the - * RWops is closed. PhysicsFS should be configured to your liking before - * opening files through this method. - * - * @param fname File to open in platform-independent notation. - * @return A valid SDL_RWops structure on success, NULL on error. Specifics - * of the error can be gleaned from PHYSFS_getLastError(). - */ -SDL_RWops *PHYSFSRWOPS_openWrite(const char *const fname) A_WARN_UNUSED; - -/** - * Open a platform-independent filename for appending, and make it accessible - * via an SDL_RWops structure. The file will be closed in PhysicsFS when the - * RWops is closed. PhysicsFS should be configured to your liking before - * opening files through this method. - * - * @param fname File to open in platform-independent notation. - * @return A valid SDL_RWops structure on success, NULL on error. Specifics - * of the error can be gleaned from PHYSFS_getLastError(). - */ -SDL_RWops *PHYSFSRWOPS_openAppend(const char *const fname) A_WARN_UNUSED; - -/** - * Make a SDL_RWops from an existing PhysicsFS file handle. You should - * dispose of any references to the handle after successful creation of - * the RWops. The actual PhysicsFS handle will be destroyed when the - * RWops is closed. - * - * @param handle a valid PhysicsFS file handle. - * @return A valid SDL_RWops structure on success, NULL on error. Specifics - * of the error can be gleaned from PHYSFS_getLastError(). - */ -SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *const handle) A_WARN_UNUSED; - -#ifdef DUMP_LEAKED_RESOURCES -void reportRWops(); -#endif // DUMP_LEAKED_RESOURCES - -#endif // UTILS_PHYSFSRWOPS_H diff --git a/src/utils/virtfsrwops.cpp b/src/utils/virtfsrwops.cpp new file mode 100644 index 000000000..adcfa2784 --- /dev/null +++ b/src/utils/virtfsrwops.cpp @@ -0,0 +1,317 @@ +/* + * This code provides a glue layer between PhysicsFS and Simple Directmedia + * Layer's (SDL) RWops i/o abstraction. + * + * License: this code is public domain. I make no warranty that it is useful, + * correct, harmless, or environmentally safe. + * + * This particular file may be used however you like, including copying it + * verbatim into a closed-source project, exploiting it commercially, and + * removing any trace of my name from the source (although I hope you won't + * do that). I welcome enhancements and corrections to this file, but I do + * not require you to send me patches if you make changes. This code has + * NO WARRANTY. + * + * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license. + * Please see LICENSE.txt in the root of the source tree. + * + * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/ + * + * This file was written by Ryan C. Gordon. (icculus@icculus.org). + * + * Copyright (C) 2012-2017 The ManaPlus Developers + */ + +#include "utils/virtfsrwops.h" + +#include "logger.h" + +#include "utils/fuzzer.h" +#include "utils/physfscheckutils.h" + +#include "debug.h" + +#ifdef USE_SDL2 +#define PHYSFSINT int64_t +#define PHYSFSSIZE size_t +#else // USE_SDL2 +#define PHYSFSINT int32_t +#define PHYSFSSIZE int +#endif // USE_SDL2 + +#ifdef DUMP_LEAKED_RESOURCES +static int openedRWops = 0; +#endif // DUMP_LEAKED_RESOURCES + +static PHYSFSINT physfsrwops_seek(SDL_RWops *const rw, + const PHYSFSINT offset, + const int whence) +{ + if (!rw) + return -1; + PHYSFS_file *const handle = static_cast( + rw->hidden.unknown.data1); + PHYSFSINT pos = 0; + + if (whence == SEEK_SET) + { + pos = offset; + } /* if */ + else if (whence == SEEK_CUR) + { + const int64_t current = VirtFs::tell(handle); + if (current == -1) + { + logger->assertLog( + "physfsrwops_seek: Can't find position in file: %s", + VirtFs::getLastError()); + return -1; + } /* if */ + + pos = CAST_S32(current); + if (static_cast(pos) != current) + { + logger->assertLog("physfsrwops_seek: " + "Can't fit current file position in an int!"); + return -1; + } /* if */ + + if (offset == 0) /* this is a "tell" call. We're done. */ + return pos; + + pos += offset; + } /* else if */ + else if (whence == SEEK_END) + { + const int64_t len = VirtFs::fileLength(handle); + if (len == -1) + { + logger->assertLog("physfsrwops_seek:Can't find end of file: %s", + VirtFs::getLastError()); + return -1; + } /* if */ + + pos = static_cast(len); + if (static_cast(pos) != len) + { + logger->assertLog("physfsrwops_seek: " + "Can't fit end-of-file position in an int!"); + return -1; + } /* if */ + + pos += offset; + } /* else if */ + else + { + logger->assertLog("physfsrwops_seek: Invalid 'whence' parameter."); + return -1; + } /* else */ + + if (pos < 0) + { + logger->assertLog("physfsrwops_seek: " + "Attempt to seek past start of file."); + return -1; + } /* if */ + + if (!VirtFs::seek(handle, static_cast(pos))) + { + logger->assertLog("physfsrwops_seek: seek error: %s", + VirtFs::getLastError()); + return -1; + } /* if */ + + return pos; +} /* physfsrwops_seek */ + +static PHYSFSSIZE physfsrwops_read(SDL_RWops *const rw, + void *ptr, + const PHYSFSSIZE size, + const PHYSFSSIZE maxnum) +{ + if (!rw) + return 0; + PHYSFS_file *const handle = static_cast( + rw->hidden.unknown.data1); + const int64_t rc = VirtFs::read(handle, ptr, + CAST_U32(size), + CAST_U32(maxnum)); + if (rc != static_cast(maxnum)) + { + if (!VirtFs::eof(handle)) /* not EOF? Must be an error. */ + { + logger->assertLog("physfsrwops_seek: read error: %s", + PHYSFS_getLastError()); + } + } /* if */ + + return CAST_S32(rc); +} /* physfsrwops_read */ + +static PHYSFSSIZE physfsrwops_write(SDL_RWops *const rw, const void *ptr, + const PHYSFSSIZE size, + const PHYSFSSIZE num) +{ + if (!rw) + return 0; + PHYSFS_file *const handle = static_cast( + rw->hidden.unknown.data1); + const int64_t rc = VirtFs::write(handle, ptr, + CAST_U32(size), + CAST_U32(num)); + if (rc != static_cast(num)) + { + logger->assertLog("physfsrwops_seek: write error: %s", + PHYSFS_getLastError()); + } + + return CAST_S32(rc); +} /* physfsrwops_write */ + +static int physfsrwops_close(SDL_RWops *const rw) +{ + if (!rw) + return 0; + PHYSFS_file *const handle = static_cast( + rw->hidden.unknown.data1); + if (!VirtFs::close(handle)) + { + logger->assertLog("physfsrwops_seek: close error: %s", + VirtFs::getLastError()); + return -1; + } /* if */ + + SDL_FreeRW(rw); +#ifdef DUMP_LEAKED_RESOURCES + if (openedRWops <= 0) + logger->assertLog("physfsrwops_seek: closing already closed RWops"); + openedRWops --; +#endif // DUMP_LEAKED_RESOURCES +#ifdef DEBUG_PHYSFS + FakePhysFSClose(rw); +#endif // DEBUG_PHYSFS + + return 0; +} /* physfsrwops_close */ + +#ifdef USE_SDL2 +static PHYSFSINT physfsrwops_size(SDL_RWops *const rw) +{ + PHYSFS_file *const handle = static_cast( + rw->hidden.unknown.data1); + return VirtFs::fileLength(handle); +} /* physfsrwops_size */ +#endif // USE_SDL2 + +static SDL_RWops *create_rwops(PHYSFS_file *const handle) +{ + SDL_RWops *retval = nullptr; + + if (!handle) + { + logger->assertLog("physfsrwops_seek: create rwops error: %s", + VirtFs::getLastError()); + } + else + { + retval = SDL_AllocRW(); + if (retval) + { +#ifdef USE_SDL2 + retval->size = &physfsrwops_size; +#endif // USE_SDL2 + + retval->seek = &physfsrwops_seek; + retval->read = &physfsrwops_read; + retval->write = &physfsrwops_write; + retval->close = &physfsrwops_close; + retval->hidden.unknown.data1 = handle; + } /* if */ +#ifdef DUMP_LEAKED_RESOURCES + openedRWops ++; +#endif // DUMP_LEAKED_RESOURCES + } /* else */ + + return retval; +} /* create_rwops */ + +SDL_RWops *VirtFs::MakeRWops(PHYSFS_file *const handle) +{ + SDL_RWops *retval = nullptr; + if (!handle) + { + logger->assertLog("physfsrwops_seek: NULL pointer passed to " + "RWopsmakeRWops()."); + } + else + { + retval = create_rwops(handle); + } + + return retval; +} /* RWopsmakeRWops */ + +#ifdef __APPLE__ +static bool checkFilePath(const char *const fname) +{ + if (!fname || !*fname) + return false; + if (!VirtFs::exists(fname) || VirtFs::isDirectory(fname)) + return false; + return true; +} +#endif // __APPLE__ + +SDL_RWops *VirtFs::RWopsOpenRead(const char *const fname) +{ + BLOCK_START("RWopsopenRead") +#ifdef __APPLE__ + if (!checkFilePath(fname)) + return nullptr; +#endif // __APPLE__ +#ifdef USE_FUZZER + if (Fuzzer::conditionTerminate(fname)) + return nullptr; +#endif // USE_FUZZER +#ifdef USE_PROFILER + SDL_RWops *const ret = create_rwops(VirtFs::openRead(fname)); + BLOCK_END("RWopsopenRead") + return ret; +#else // USE_PROFILER + + return create_rwops(VirtFs::openRead(fname)); +#endif // USE_PROFILER +} /* RWopsopenRead */ + +SDL_RWops *VirtFs::RWopsOpenWrite(const char *const fname) +{ +#ifdef __APPLE__ + if (!checkFilePath(fname)) + return nullptr; +#endif // __APPLE__ + + return create_rwops(VirtFs::openWrite(fname)); +} /* RWopsopenWrite */ + +SDL_RWops *VirtFs::RWopsOpenAppend(const char *const fname) +{ +#ifdef __APPLE__ + if (!checkFilePath(fname)) + return nullptr; +#endif // __APPLE__ + + return create_rwops(VirtFs::openAppend(fname)); +} /* RWopsopenAppend */ + +#ifdef DUMP_LEAKED_RESOURCES +void VirtFs::reportRWops() +{ + if (openedRWops) + { + logger->assertLog("physfsrwops_seek: leaking RWops: %d", + openedRWops); + } +} +#endif // DUMP_LEAKED_RESOURCES + +/* end of physfsrwops.c ... */ diff --git a/src/utils/virtfsrwops.h b/src/utils/virtfsrwops.h new file mode 100644 index 000000000..83aa79996 --- /dev/null +++ b/src/utils/virtfsrwops.h @@ -0,0 +1,45 @@ +/* + * This code provides a glue layer between PhysicsFS and Simple Directmedia + * Layer's (SDL) RWops i/o abstraction. + * + * License: this code is public domain. I make no warranty that it is useful, + * correct, harmless, or environmentally safe. + * + * This particular file may be used however you like, including copying it + * verbatim into a closed-source project, exploiting it commercially, and + * removing any trace of my name from the source (although I hope you won't + * do that). I welcome enhancements and corrections to this file, but I do + * not require you to send me patches if you make changes. This code has + * NO WARRANTY. + * + * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license. + * Please see LICENSE.txt in the root of the source tree. + * + * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/ + * + * This file was written by Ryan C. Gordon. (icculus@icculus.org). + * + * Copyright (C) 2012-2017 The ManaPlus Developers + */ + +#ifndef UTILS_PHYSFSRWOPS_H +#define UTILS_PHYSFSRWOPS_H + +#include "localconsts.h" + +#include + +#include "utils/virtfs.h" + +namespace VirtFs +{ + SDL_RWops *RWopsOpenRead(const char *const fname) A_WARN_UNUSED; + SDL_RWops *RWopsOpenWrite(const char *const fname) A_WARN_UNUSED; + SDL_RWops *RWopsOpenAppend(const char *const fname) A_WARN_UNUSED; + SDL_RWops *MakeRWops(PHYSFS_file *const handle) A_WARN_UNUSED; +#ifdef DUMP_LEAKED_RESOURCES + void reportRWops(); +#endif // DUMP_LEAKED_RESOURCES +} // namespace VirtFs + +#endif // UTILS_PHYSFSRWOPS_H -- cgit v1.2.3-60-g2f50