summaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/virtfile.cpp36
-rw-r--r--src/utils/virtfile.h39
-rw-r--r--src/utils/virtfileprivate.cpp42
-rw-r--r--src/utils/virtfileprivate.h44
-rw-r--r--src/utils/virtfs.cpp78
-rw-r--r--src/utils/virtfs.h29
-rw-r--r--src/utils/virtfsrwops.cpp21
-rw-r--r--src/utils/virtfsrwops.h4
8 files changed, 245 insertions, 48 deletions
diff --git a/src/utils/virtfile.cpp b/src/utils/virtfile.cpp
new file mode 100644
index 000000000..b7e6cce1f
--- /dev/null
+++ b/src/utils/virtfile.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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 "utils/virtfile.h"
+
+#include "utils/delete2.h"
+#include "utils/virtfileprivate.h"
+
+#include "debug.h"
+
+VirtFile::VirtFile() :
+ mPrivate(nullptr)
+{
+}
+
+VirtFile::~VirtFile()
+{
+ delete2(mPrivate);
+}
diff --git a/src/utils/virtfile.h b/src/utils/virtfile.h
new file mode 100644
index 000000000..cf7ded1a4
--- /dev/null
+++ b/src/utils/virtfile.h
@@ -0,0 +1,39 @@
+/*
+ * 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_VIRTFILE_H
+#define UTILS_VIRTFILE_H
+
+#include "localconsts.h"
+
+struct VirtFilePrivate;
+
+struct VirtFile final
+{
+ VirtFile();
+
+ A_DELETE_COPY(VirtFile)
+
+ ~VirtFile();
+
+ VirtFilePrivate *mPrivate;
+};
+
+#endif // UTILS_VIRTFILE_H
diff --git a/src/utils/virtfileprivate.cpp b/src/utils/virtfileprivate.cpp
new file mode 100644
index 000000000..e1a5885f7
--- /dev/null
+++ b/src/utils/virtfileprivate.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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 "utils/virtfileprivate.h"
+
+#include "debug.h"
+
+VirtFilePrivate::VirtFilePrivate() :
+ mFile(nullptr)
+{
+}
+
+VirtFilePrivate::VirtFilePrivate(PHYSFS_file *const file) :
+ mFile(file)
+{
+}
+
+VirtFilePrivate::~VirtFilePrivate()
+{
+ if (mFile != nullptr)
+ {
+ PHYSFS_close(mFile);
+ mFile = nullptr;
+ }
+}
diff --git a/src/utils/virtfileprivate.h b/src/utils/virtfileprivate.h
new file mode 100644
index 000000000..59670d858
--- /dev/null
+++ b/src/utils/virtfileprivate.h
@@ -0,0 +1,44 @@
+/*
+ * 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
+{
+ VirtFilePrivate();
+
+ VirtFilePrivate(PHYSFS_file *const file);
+
+ A_DELETE_COPY(VirtFilePrivate)
+
+ ~VirtFilePrivate();
+
+ PHYSFS_file *mFile;
+};
+
+#endif // UTILS_VIRTFILEPRIVATE_H
diff --git a/src/utils/virtfs.cpp b/src/utils/virtfs.cpp
index af000376a..6d3d18ba9 100644
--- a/src/utils/virtfs.cpp
+++ b/src/utils/virtfs.cpp
@@ -22,6 +22,9 @@
#include "logger.h"
+#include "utils/virtfile.h"
+#include "utils/virtfileprivate.h"
+
#include <iostream>
#include <unistd.h>
@@ -98,19 +101,34 @@ namespace VirtFs
PHYSFS_freeList(listVar);
}
- PHYSFS_file *openRead(const char *const filename)
+ VirtFile *openRead(const char *const filename)
{
- return PHYSFS_openRead(filename);
+ PHYSFS_file *const handle = PHYSFS_openRead(filename);
+ if (!handle)
+ return nullptr;
+ VirtFile *const file = new VirtFile;
+ file->mPrivate = new VirtFilePrivate(handle);
+ return file;
}
- PHYSFS_file *openWrite(const char *const filename)
+ VirtFile *openWrite(const char *const filename)
{
- return PHYSFS_openWrite(filename);
+ PHYSFS_file *const handle = PHYSFS_openWrite(filename);
+ if (!handle)
+ return nullptr;
+ VirtFile *const file = new VirtFile;
+ file->mPrivate = new VirtFilePrivate(handle);
+ return file;
}
- PHYSFS_file *openAppend(const char *const filename)
+ VirtFile *openAppend(const char *const filename)
{
- return PHYSFS_openAppend(filename);
+ PHYSFS_file *const handle = PHYSFS_openAppend(filename);
+ if (!handle)
+ return nullptr;
+ VirtFile *const file = new VirtFile;
+ file->mPrivate = new VirtFilePrivate(handle);
+ return file;
}
bool setWriteDir(const char *const newDir)
@@ -141,7 +159,7 @@ namespace VirtFs
void *loadFile(const std::string &fileName, int &fileSize)
{
// Attempt to open the specified file using PhysicsFS
- PHYSFS_file *const file = VirtFs::openRead(fileName.c_str());
+ VirtFile *const file = VirtFs::openRead(fileName.c_str());
if (!file)
{
@@ -185,45 +203,63 @@ namespace VirtFs
return PHYSFS_getLastError();
}
- int close(PHYSFS_file *const file)
+ int close(VirtFile *const file)
{
- return PHYSFS_close(file);
+ if (file == nullptr)
+ return 0;
+ delete file;
+ return 1;
}
- int64_t read(PHYSFS_File *const file,
+ int64_t read(VirtFile *const file,
void *const buffer,
const uint32_t objSize,
const uint32_t objCount)
{
- return PHYSFS_read(file, buffer, objSize, objCount);
+ if (file == nullptr)
+ return 0;
+ return PHYSFS_read(file->mPrivate->mFile,
+ buffer,
+ objSize,
+ objCount);
}
- int64_t write(PHYSFS_File *const file,
+ int64_t write(VirtFile *const file,
const void *const buffer,
const uint32_t objSize,
const uint32_t objCount)
{
- return PHYSFS_write(file, buffer, objSize, objCount);
+ if (file == nullptr)
+ return 0;
+ return PHYSFS_write(file->mPrivate->mFile,
+ buffer,
+ objSize,
+ objCount);
}
- int64_t fileLength(PHYSFS_File *const file)
+ int64_t fileLength(VirtFile *const file)
{
- return PHYSFS_fileLength(file);
+ if (file == nullptr)
+ return -1;
+ return PHYSFS_fileLength(file->mPrivate->mFile);
}
- int64_t tell(PHYSFS_File *const file)
+ int64_t tell(VirtFile *const file)
{
- return PHYSFS_tell(file);
+ if (file == nullptr)
+ return -1;
+ return PHYSFS_tell(file->mPrivate->mFile);
}
- int seek(PHYSFS_File *const file,
+ int seek(VirtFile *const file,
const uint64_t pos)
{
- return PHYSFS_seek(file, pos);
+ return PHYSFS_seek(file->mPrivate->mFile,
+ pos);
}
- int eof(PHYSFS_File *const file)
+ int eof(VirtFile *const file)
{
- return PHYSFS_eof(file);
+ return PHYSFS_eof(file->mPrivate->mFile);
}
} // namespace PhysFs
diff --git a/src/utils/virtfs.h b/src/utils/virtfs.h
index 66149c903..e2db24e44 100644
--- a/src/utils/virtfs.h
+++ b/src/utils/virtfs.h
@@ -23,13 +23,10 @@
#include "localconsts.h"
-PRAGMA45(GCC diagnostic push)
-PRAGMA45(GCC diagnostic ignored "-Wlong-long")
-#include <physfs.h>
-PRAGMA45(GCC diagnostic pop)
-
#include <string>
+struct VirtFile;
+
namespace VirtFs
{
void init(const char *const name);
@@ -41,9 +38,9 @@ namespace VirtFs
char **enumerateFiles(const char *const dir);
bool isDirectory(const char *const fname);
void freeList(void *const listVar);
- PHYSFS_file *openRead(const char *const filename);
- PHYSFS_file *openWrite(const char *const filename);
- PHYSFS_file *openAppend(const char *const filename);
+ VirtFile *openRead(const char *const filename);
+ VirtFile *openWrite(const char *const filename);
+ VirtFile *openAppend(const char *const filename);
bool setWriteDir(const char *const newDir);
bool addToSearchPath(const char *const newDir, const int appendToPath);
bool removeFromSearchPath(const char *const oldDir);
@@ -53,21 +50,21 @@ namespace VirtFs
bool deinit();
void permitLinks(const bool val);
const char *getLastError();
- int64_t read(PHYSFS_File *const handle,
+ int64_t read(VirtFile *const handle,
void *const buffer,
const uint32_t objSize,
const uint32_t objCount);
- int64_t write(PHYSFS_File *const file,
+ int64_t write(VirtFile *const file,
const void *const buffer,
const uint32_t objSize,
const uint32_t objCount);
- int close(PHYSFS_file *const file);
- int64_t fileLength(PHYSFS_File *const file);
- int64_t tell(PHYSFS_File *const file);
- int seek(PHYSFS_File *const file,
+ int close(VirtFile *const file);
+ int64_t fileLength(VirtFile *const file);
+ int64_t tell(VirtFile *const file);
+ int seek(VirtFile *const file,
const uint64_t pos);
- int eof(PHYSFS_File *const file);
-} // namespace PhysFs
+ int eof(VirtFile *const file);
+} // namespace VirtFs
extern const char *dirSeparator;
diff --git a/src/utils/virtfsrwops.cpp b/src/utils/virtfsrwops.cpp
index 731eb12a8..ce4f0cec9 100644
--- a/src/utils/virtfsrwops.cpp
+++ b/src/utils/virtfsrwops.cpp
@@ -53,6 +53,9 @@
#endif // DEBUG_VIRTFS
#include "utils/fuzzer.h"
+#include "utils/virtfile.h"
+#include "utils/virtfileprivate.h"
+#include "utils/virtfs.h"
#include "debug.h"
@@ -138,7 +141,7 @@ static RWOPSINT virtfsrwops_seek(SDL_RWops *const rw,
{
if (!rw)
return -1;
- PHYSFS_file *const handle = static_cast<PHYSFS_file *const>(
+ VirtFile *const handle = static_cast<VirtFile *const>(
rw->hidden.unknown.data1);
RWOPSINT pos = 0;
@@ -220,7 +223,7 @@ static RWOPSSIZE virtfsrwops_read(SDL_RWops *const rw,
{
if (!rw)
return 0;
- PHYSFS_file *const handle = static_cast<PHYSFS_file *const>(
+ VirtFile *const handle = static_cast<VirtFile *const>(
rw->hidden.unknown.data1);
const int64_t rc = VirtFs::read(handle, ptr,
CAST_U32(size),
@@ -244,7 +247,7 @@ static RWOPSSIZE virtfsrwops_write(SDL_RWops *const rw,
{
if (!rw)
return 0;
- PHYSFS_file *const handle = static_cast<PHYSFS_file *const>(
+ VirtFile *const handle = static_cast<VirtFile *const>(
rw->hidden.unknown.data1);
const int64_t rc = VirtFs::write(handle, ptr,
CAST_U32(size),
@@ -262,7 +265,7 @@ static int virtfsrwops_close(SDL_RWops *const rw)
{
if (!rw)
return 0;
- PHYSFS_file *const handle = static_cast<PHYSFS_file*>(
+ VirtFile *const handle = static_cast<VirtFile*>(
rw->hidden.unknown.data1);
if (!VirtFs::close(handle))
{
@@ -287,17 +290,17 @@ static int virtfsrwops_close(SDL_RWops *const rw)
#ifdef USE_SDL2
static RWOPSINT virtfsrwops_size(SDL_RWops *const rw)
{
- PHYSFS_file *const handle = static_cast<PHYSFS_file*>(
+ VirtFile *const handle = static_cast<VirtFile *const>(
rw->hidden.unknown.data1);
return VirtFs::fileLength(handle);
} /* virtfsrwops_size */
#endif // USE_SDL2
-static SDL_RWops *create_rwops(PHYSFS_file *const handle)
+static SDL_RWops *create_rwops(VirtFile *const file)
{
SDL_RWops *retval = nullptr;
- if (!handle)
+ if (!file)
{
logger->assertLog("virtfsrwops_seek: create rwops error: %s",
VirtFs::getLastError());
@@ -315,7 +318,7 @@ static SDL_RWops *create_rwops(PHYSFS_file *const handle)
retval->read = &virtfsrwops_read;
retval->write = &virtfsrwops_write;
retval->close = &virtfsrwops_close;
- retval->hidden.unknown.data1 = handle;
+ retval->hidden.unknown.data1 = file;
} /* if */
#ifdef DUMP_LEAKED_RESOURCES
openedRWops ++;
@@ -325,7 +328,7 @@ static SDL_RWops *create_rwops(PHYSFS_file *const handle)
return retval;
} /* create_rwops */
-SDL_RWops *VirtFs::MakeRWops(PHYSFS_file *const handle)
+SDL_RWops *VirtFs::MakeRWops(VirtFile *const handle)
{
SDL_RWops *retval = nullptr;
if (!handle)
diff --git a/src/utils/virtfsrwops.h b/src/utils/virtfsrwops.h
index c937fe543..5a8871377 100644
--- a/src/utils/virtfsrwops.h
+++ b/src/utils/virtfsrwops.h
@@ -49,7 +49,7 @@
#include <SDL_rwops.h>
-#include "utils/virtfs.h"
+struct VirtFile;
namespace VirtFs
{
@@ -64,7 +64,7 @@ namespace VirtFs
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;
+ SDL_RWops *MakeRWops(VirtFile *const handle) A_WARN_UNUSED;
#ifdef DUMP_LEAKED_RESOURCES
void reportRWops();
#endif // DUMP_LEAKED_RESOURCES