summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2017-03-29 23:58:34 +0300
committerAndrei Karas <akaras@inbox.ru>2017-03-29 23:58:34 +0300
commit7c377321ca62168658499f9753b9475a276d4506 (patch)
tree922c48d550afc3486987a62ec8df2fa47aec5c6c /src
parent11b1979a4dd43ff9b6788a8c95eec945ad5fde5a (diff)
downloadmanaverse-7c377321ca62168658499f9753b9475a276d4506.tar.gz
manaverse-7c377321ca62168658499f9753b9475a276d4506.tar.bz2
manaverse-7c377321ca62168658499f9753b9475a276d4506.tar.xz
manaverse-7c377321ca62168658499f9753b9475a276d4506.zip
Move rwops functions into virtfsdir and virtfszip without optimisations.
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt8
-rw-r--r--src/Makefile.am4
-rw-r--r--src/fs/virtfs/virtfsdir.cpp8
-rw-r--r--src/fs/virtfs/virtfsdirrwops.cpp182
-rw-r--r--src/fs/virtfs/virtfsdirrwops.h50
-rw-r--r--src/fs/virtfs/virtfsfuncs.h28
-rw-r--r--src/fs/virtfs/virtfsrwops.cpp158
-rw-r--r--src/fs/virtfs/virtfsrwops.h15
-rw-r--r--src/fs/virtfs/virtfszip.cpp8
-rw-r--r--src/fs/virtfs/virtfsziprwops.cpp182
-rw-r--r--src/fs/virtfs/virtfsziprwops.h50
11 files changed, 526 insertions, 167 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 85ae478d2..432da847a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -896,10 +896,14 @@ SET(SRCS
fs/virtfs/virtdirentry.h
fs/virtfs/virtfsdir.cpp
fs/virtfs/virtfsdir.h
+ fs/virtfs/virtfsdirrwops.cpp
+ fs/virtfs/virtfsdirrwops.h
fs/virtfs/virtfsentry.cpp
fs/virtfs/virtfsentry.h
fs/virtfs/virtfszip.cpp
fs/virtfs/virtfszip.h
+ fs/virtfs/virtfsziprwops.cpp
+ fs/virtfs/virtfsziprwops.h
fs/virtfs/virtzipentry.cpp
fs/virtfs/virtzipentry.h
fs/virtfs/zip.cpp
@@ -1796,10 +1800,14 @@ SET(DYE_CMD_SRCS
fs/virtfs/virtdirentry.h
fs/virtfs/virtfsdir.cpp
fs/virtfs/virtfsdir.h
+ fs/virtfs/virtfsdirrwops.cpp
+ fs/virtfs/virtfsdirrwops.h
fs/virtfs/virtfsentry.cpp
fs/virtfs/virtfsentry.h
fs/virtfs/virtfszip.cpp
fs/virtfs/virtfszip.h
+ fs/virtfs/virtfsziprwops.cpp
+ fs/virtfs/virtfsziprwops.h
fs/virtfs/virtzipentry.cpp
fs/virtfs/virtzipentry.h
fs/virtfs/zip.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index c6b35a6df..193d5b8ca 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -843,10 +843,14 @@ BASE_SRC += events/actionevent.h \
fs/virtfs/virtfs.h \
fs/virtfs/virtfsdir.cpp \
fs/virtfs/virtfsdir.h \
+ fs/virtfs/virtfsdirrwops.cpp \
+ fs/virtfs/virtfsdirrwops.h \
fs/virtfs/virtfsentry.cpp \
fs/virtfs/virtfsentry.h \
fs/virtfs/virtfszip.cpp \
fs/virtfs/virtfszip.h \
+ fs/virtfs/virtfsziprwops.cpp \
+ fs/virtfs/virtfsziprwops.h \
fs/virtfs/virtzipentry.cpp \
fs/virtfs/virtzipentry.h \
fs/virtfs/zip.cpp \
diff --git a/src/fs/virtfs/virtfsdir.cpp b/src/fs/virtfs/virtfsdir.cpp
index b6f197ae3..c3c2cad73 100644
--- a/src/fs/virtfs/virtfsdir.cpp
+++ b/src/fs/virtfs/virtfsdir.cpp
@@ -26,6 +26,7 @@
#include "fs/virtfs/virtdirentry.h"
#include "fs/virtfs/virtfile.h"
+#include "fs/virtfs/virtfsdirrwops.h"
#include "fs/virtfs/virtfsfuncs.h"
#include "fs/virtfs/virtlist.h"
@@ -136,6 +137,13 @@ namespace VirtFsDir
ptr->openWrite = &VirtFsDir::openWrite;
ptr->openAppend = &VirtFsDir::openAppend;
ptr->loadFile = &VirtFsDir::loadFile;
+ ptr->rwops_seek = &VirtFsDir::rwops_seek;
+ ptr->rwops_read = &VirtFsDir::rwops_read;
+ ptr->rwops_write = &VirtFsDir::rwops_write;
+ ptr->rwops_close = &VirtFsDir::rwops_close;
+#ifdef USE_SDL2
+ ptr->rwops_size = &VirtFsDir::rwops_size;
+#endif // USE_SDL2
}
VirtFsFuncs *getFuncs()
diff --git a/src/fs/virtfs/virtfsdirrwops.cpp b/src/fs/virtfs/virtfsdirrwops.cpp
new file mode 100644
index 000000000..428e416b3
--- /dev/null
+++ b/src/fs/virtfs/virtfsdirrwops.cpp
@@ -0,0 +1,182 @@
+/*
+ * 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/virtfsdirrwops.h"
+
+#include "logger.h"
+
+#include "fs/virtfs/virtfile.h"
+#include "fs/virtfs/virtfs.h"
+
+#include <SDL_rwops.h>
+
+#include "debug.h"
+
+namespace VirtFsDir
+{
+ RWOPSINT rwops_seek(SDL_RWops *const rw,
+ const RWOPSINT offset,
+ const int whence)
+ {
+ if (!rw)
+ return -1;
+ VirtFile *const handle = static_cast<VirtFile *const>(
+ rw->hidden.unknown.data1);
+ RWOPSINT pos = 0;
+
+ if (whence == SEEK_SET)
+ {
+ pos = offset;
+ }
+ else if (whence == SEEK_CUR)
+ {
+ const int64_t current = VirtFs::tell(handle);
+ if (current == -1)
+ {
+ logger->assertLog(
+ "VirtFs::rwops_seek: Can't find position in file.");
+ return -1;
+ }
+
+ pos = CAST_S32(current);
+ if (static_cast<int64_t>(pos) != current)
+ {
+ logger->assertLog("VirtFs::rwops_seek: "
+ "Can't fit current file position in an int!");
+ return -1;
+ }
+
+ if (offset == 0) /* this is a "tell" call. We're done. */
+ return pos;
+
+ pos += offset;
+ }
+ else if (whence == SEEK_END)
+ {
+ const int64_t len = VirtFs::fileLength(handle);
+ if (len == -1)
+ {
+ logger->assertLog(
+ "VirtFs::rwops_seek:Can't find end of file.");
+ return -1;
+ }
+
+ pos = static_cast<RWOPSINT>(len);
+ if (static_cast<int64_t>(pos) != len)
+ {
+ logger->assertLog("VirtFs::rwops_seek: "
+ "Can't fit end-of-file position in an int!");
+ return -1;
+ }
+
+ pos += offset;
+ }
+ else
+ {
+ logger->assertLog(
+ "VirtFs::rwops_seek: Invalid 'whence' parameter.");
+ return -1;
+ }
+
+ if (pos < 0)
+ {
+ logger->assertLog("VirtFs::rwops_seek: "
+ "Attempt to seek past start of file.");
+ return -1;
+ }
+
+ if (!VirtFs::seek(handle, static_cast<uint64_t>(pos)))
+ {
+ logger->assertLog("VirtFs::rwops_seek: seek error.");
+ return -1;
+ }
+
+ return pos;
+ }
+
+ RWOPSSIZE rwops_read(SDL_RWops *const rw,
+ void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE maxnum)
+ {
+ if (!rw)
+ return 0;
+ VirtFile *const handle = static_cast<VirtFile *const>(
+ rw->hidden.unknown.data1);
+ const int64_t rc = VirtFs::read(handle, ptr,
+ CAST_U32(size),
+ CAST_U32(maxnum));
+ if (rc != static_cast<int64_t>(maxnum))
+ {
+ if (!VirtFs::eof(handle)) /* not EOF? Must be an error. */
+ {
+ logger->assertLog("VirtFs::rwops_seek: read error.");
+ }
+ }
+
+ return CAST_S32(rc);
+ }
+
+ RWOPSSIZE rwops_write(SDL_RWops *const rw,
+ const void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE num)
+ {
+ if (!rw)
+ return 0;
+ VirtFile *const handle = static_cast<VirtFile *const>(
+ rw->hidden.unknown.data1);
+ const int64_t rc = VirtFs::write(handle, ptr,
+ CAST_U32(size),
+ CAST_U32(num));
+ if (rc != static_cast<int64_t>(num))
+ {
+ logger->assertLog("VirtFs::rwops_seek: write error.");
+ }
+
+ return CAST_S32(rc);
+ }
+
+ int rwops_close(SDL_RWops *const rw)
+ {
+ if (!rw)
+ return 0;
+ VirtFile *const handle = static_cast<VirtFile*>(
+ rw->hidden.unknown.data1);
+ if (!VirtFs::close(handle))
+ {
+ logger->assertLog("VirtFs::rwops_seek: close error.");
+ return -1;
+ }
+
+ SDL_FreeRW(rw);
+ return 0;
+ }
+
+#ifdef USE_SDL2
+ RWOPSINT rwops_size(SDL_RWops *const rw)
+ {
+ VirtFile *const handle = static_cast<VirtFile *const>(
+ rw->hidden.unknown.data1);
+ return VirtFs::fileLength(handle);
+ }
+#endif // USE_SDL2
+
+} // namespace VirtFsDir
diff --git a/src/fs/virtfs/virtfsdirrwops.h b/src/fs/virtfs/virtfsdirrwops.h
new file mode 100644
index 000000000..d8f5c7d15
--- /dev/null
+++ b/src/fs/virtfs/virtfsdirrwops.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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UTILS_VIRTFS_VIRTFSDIRRWOPS_H
+#define UTILS_VIRTFS_VIRTFSDIRRWOPS_H
+
+#include "fs/virtfs/rwopstypes.h"
+
+struct SDL_RWops;
+
+#include "localconsts.h"
+
+namespace VirtFsDir
+{
+ RWOPSINT rwops_seek(SDL_RWops *const rw,
+ const RWOPSINT offset,
+ const int whence);
+ RWOPSSIZE rwops_read(SDL_RWops *const rw,
+ void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE maxnum);
+ RWOPSSIZE rwops_write(SDL_RWops *const rw,
+ const void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE num);
+ int rwops_close(SDL_RWops *const rw);
+#ifdef USE_SDL2
+ RWOPSINT rwops_size(SDL_RWops *const rw);
+#endif // USE_SDL2
+
+} // namespace VirtFsDir
+
+#endif // UTILS_VIRTFS_VIRTFSDIRRWOPS_H
diff --git a/src/fs/virtfs/virtfsfuncs.h b/src/fs/virtfs/virtfsfuncs.h
index 21b7a3220..84345679b 100644
--- a/src/fs/virtfs/virtfsfuncs.h
+++ b/src/fs/virtfs/virtfsfuncs.h
@@ -21,12 +21,15 @@
#ifndef UTILS_VIRTFSFUNCS_H
#define UTILS_VIRTFSFUNCS_H
+#include "fs/virtfs/rwopstypes.h"
+
#include "utils/stringvector.h"
#include "localconsts.h"
struct VirtFile;
struct VirtFsEntry;
+struct SDL_RWops;
struct VirtFsFuncs final
{
@@ -45,7 +48,14 @@ struct VirtFsFuncs final
openWrite(nullptr),
openAppend(nullptr),
eof(nullptr),
- loadFile(nullptr)
+ loadFile(nullptr),
+ rwops_seek(nullptr),
+ rwops_read(nullptr),
+ rwops_write(nullptr),
+#ifdef USE_SDL2
+ rwops_size(nullptr),
+#endif // USE_SDL2
+ rwops_close(nullptr)
{
}
@@ -87,6 +97,22 @@ struct VirtFsFuncs final
const char *(*loadFile) (VirtFsEntry *restrict const entry,
const std::string &restrict fileName,
int &restrict fileSize);
+
+ RWOPSINT (*rwops_seek) (SDL_RWops *const rw,
+ const RWOPSINT offset,
+ const int whence);
+ RWOPSSIZE (*rwops_read) (SDL_RWops *const rw,
+ void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE maxnum);
+ RWOPSSIZE (*rwops_write) (SDL_RWops *const rw,
+ const void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE num);
+#ifdef USE_SDL2
+ RWOPSINT (*rwops_size) (SDL_RWops *const rw);
+#endif // USE_SDL2
+ int (*rwops_close) (SDL_RWops *const rw);
};
#endif // UTILS_VIRTFSFUNCS_H
diff --git a/src/fs/virtfs/virtfsrwops.cpp b/src/fs/virtfs/virtfsrwops.cpp
index c354b2e14..8b5dc57b0 100644
--- a/src/fs/virtfs/virtfsrwops.cpp
+++ b/src/fs/virtfs/virtfsrwops.cpp
@@ -46,158 +46,14 @@
#include "logger.h"
+#include "fs/virtfs/virtfile.h"
#include "fs/virtfs/virtfs.h"
+#include "fs/virtfs/virtfsfuncs.h"
#include "utils/fuzzer.h"
#include "debug.h"
-RWOPSINT VirtFs::rwops_seek(SDL_RWops *const rw,
- const RWOPSINT offset,
- const int whence)
-{
- if (!rw)
- return -1;
- VirtFile *const handle = static_cast<VirtFile *const>(
- rw->hidden.unknown.data1);
- RWOPSINT 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(
- "VirtFs::rwops_seek: Can't find position in file.");
- return -1;
- } /* if */
-
- pos = CAST_S32(current);
- if (static_cast<int64_t>(pos) != current)
- {
- logger->assertLog("VirtFs::rwops_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("VirtFs::rwops_seek:Can't find end of file.");
- return -1;
- } /* if */
-
- pos = static_cast<RWOPSINT>(len);
- if (static_cast<int64_t>(pos) != len)
- {
- logger->assertLog("VirtFs::rwops_seek: "
- "Can't fit end-of-file position in an int!");
- return -1;
- } /* if */
-
- pos += offset;
- } /* else if */
- else
- {
- logger->assertLog("VirtFs::rwops_seek: Invalid 'whence' parameter.");
- return -1;
- } /* else */
-
- if (pos < 0)
- {
- logger->assertLog("VirtFs::rwops_seek: "
- "Attempt to seek past start of file.");
- return -1;
- } /* if */
-
- if (!VirtFs::seek(handle, static_cast<uint64_t>(pos)))
- {
- logger->assertLog("VirtFs::rwops_seek: seek error.");
- return -1;
- } /* if */
-
- return pos;
-} /* VirtFs::rwops_seek */
-
-RWOPSSIZE VirtFs::rwops_read(SDL_RWops *const rw,
- void *const ptr,
- const RWOPSSIZE size,
- const RWOPSSIZE maxnum)
-{
- if (!rw)
- return 0;
- VirtFile *const handle = static_cast<VirtFile *const>(
- rw->hidden.unknown.data1);
- const int64_t rc = VirtFs::read(handle, ptr,
- CAST_U32(size),
- CAST_U32(maxnum));
- if (rc != static_cast<int64_t>(maxnum))
- {
- if (!VirtFs::eof(handle)) /* not EOF? Must be an error. */
- {
- logger->assertLog("VirtFs::rwops_seek: read error.");
- }
- } /* if */
-
- return CAST_S32(rc);
-} /* VirtFs::rwops_read */
-
-RWOPSSIZE VirtFs::rwops_write(SDL_RWops *const rw,
- const void *const ptr,
- const RWOPSSIZE size,
- const RWOPSSIZE num)
-{
- if (!rw)
- return 0;
- VirtFile *const handle = static_cast<VirtFile *const>(
- rw->hidden.unknown.data1);
- const int64_t rc = VirtFs::write(handle, ptr,
- CAST_U32(size),
- CAST_U32(num));
- if (rc != static_cast<int64_t>(num))
- {
- logger->assertLog("VirtFs::rwops_seek: write error.");
- }
-
- return CAST_S32(rc);
-} /* VirtFs::rwops_write */
-
-int VirtFs::rwops_close(SDL_RWops *const rw)
-{
- if (!rw)
- return 0;
- VirtFile *const handle = static_cast<VirtFile*>(
- rw->hidden.unknown.data1);
- if (!VirtFs::close(handle))
- {
- logger->assertLog("VirtFs::rwops_seek: close error.");
- return -1;
- } /* if */
-
- SDL_FreeRW(rw);
- return 0;
-} /* VirtFs::rwops_close */
-
-#ifdef USE_SDL2
-RWOPSINT VirtFs::rwops_size(SDL_RWops *const rw)
-{
- VirtFile *const handle = static_cast<VirtFile *const>(
- rw->hidden.unknown.data1);
- return VirtFs::fileLength(handle);
-} /* VirtFs::rwops_size */
-#endif // USE_SDL2
-
SDL_RWops *VirtFs::create_rwops(VirtFile *const file)
{
SDL_RWops *retval = nullptr;
@@ -212,13 +68,13 @@ SDL_RWops *VirtFs::create_rwops(VirtFile *const file)
if (retval)
{
#ifdef USE_SDL2
- retval->size = &VirtFs::rwops_size;
+ retval->size = file->funcs->rwops_size;
#endif // USE_SDL2
- retval->seek = &VirtFs::rwops_seek;
- retval->read = &VirtFs::rwops_read;
- retval->write = &VirtFs::rwops_write;
- retval->close = &VirtFs::rwops_close;
+ retval->seek = file->funcs->rwops_seek;
+ retval->read = file->funcs->rwops_read;
+ retval->write = file->funcs->rwops_write;
+ retval->close = file->funcs->rwops_close;
retval->hidden.unknown.data1 = file;
} /* if */
} /* else */
diff --git a/src/fs/virtfs/virtfsrwops.h b/src/fs/virtfs/virtfsrwops.h
index cc3fe55cf..28990706e 100644
--- a/src/fs/virtfs/virtfsrwops.h
+++ b/src/fs/virtfs/virtfsrwops.h
@@ -57,21 +57,6 @@ struct VirtFile;
namespace VirtFs
{
SDL_RWops *create_rwops(VirtFile *const file);
- RWOPSINT rwops_seek(SDL_RWops *const rw,
- const RWOPSINT offset,
- const int whence);
- RWOPSSIZE rwops_read(SDL_RWops *const rw,
- void *const ptr,
- const RWOPSSIZE size,
- const RWOPSSIZE maxnum);
- RWOPSSIZE rwops_write(SDL_RWops *const rw,
- const void *const ptr,
- const RWOPSSIZE size,
- const RWOPSSIZE num);
- int rwops_close(SDL_RWops *const rw);
-#ifdef USE_SDL2
- RWOPSINT rwops_size(SDL_RWops *const rw);
-#endif // USE_SDL2
SDL_RWops *rwopsOpenRead(const std::string &restrict fname);
SDL_RWops *rwopsOpenWrite(const std::string &restrict fname) A_WARN_UNUSED;
diff --git a/src/fs/virtfs/virtfszip.cpp b/src/fs/virtfs/virtfszip.cpp
index d344a4c64..8999cb54c 100644
--- a/src/fs/virtfs/virtfszip.cpp
+++ b/src/fs/virtfs/virtfszip.cpp
@@ -22,6 +22,7 @@
#include "fs/virtfs/virtfile.h"
#include "fs/virtfs/virtfsfuncs.h"
+#include "fs/virtfs/virtfsziprwops.h"
#include "fs/virtfs/virtlist.h"
#include "fs/virtfs/virtzipentry.h"
#include "fs/virtfs/zip.h"
@@ -72,6 +73,13 @@ namespace VirtFsZip
ptr->openWrite = &VirtFsZip::openWrite;
ptr->openAppend = &VirtFsZip::openAppend;
ptr->loadFile = &VirtFsZip::loadFile;
+ ptr->rwops_seek = &VirtFsZip::rwops_seek;
+ ptr->rwops_read = &VirtFsZip::rwops_read;
+ ptr->rwops_write = &VirtFsZip::rwops_write;
+ ptr->rwops_close = &VirtFsZip::rwops_close;
+#ifdef USE_SDL2
+ ptr->rwops_size = &VirtFsZip::rwops_size;
+#endif // USE_SDL2
}
bool getRealDir(VirtFsEntry *restrict const entry,
diff --git a/src/fs/virtfs/virtfsziprwops.cpp b/src/fs/virtfs/virtfsziprwops.cpp
new file mode 100644
index 000000000..094d0c4b0
--- /dev/null
+++ b/src/fs/virtfs/virtfsziprwops.cpp
@@ -0,0 +1,182 @@
+/*
+ * 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/virtfsziprwops.h"
+
+#include "logger.h"
+
+#include "fs/virtfs/virtfile.h"
+#include "fs/virtfs/virtfs.h"
+
+#include <SDL_rwops.h>
+
+#include "debug.h"
+
+namespace VirtFsZip
+{
+ RWOPSINT rwops_seek(SDL_RWops *const rw,
+ const RWOPSINT offset,
+ const int whence)
+ {
+ if (!rw)
+ return -1;
+ VirtFile *const handle = static_cast<VirtFile *const>(
+ rw->hidden.unknown.data1);
+ RWOPSINT pos = 0;
+
+ if (whence == SEEK_SET)
+ {
+ pos = offset;
+ }
+ else if (whence == SEEK_CUR)
+ {
+ const int64_t current = VirtFs::tell(handle);
+ if (current == -1)
+ {
+ logger->assertLog(
+ "VirtFs::rwops_seek: Can't find position in file.");
+ return -1;
+ }
+
+ pos = CAST_S32(current);
+ if (static_cast<int64_t>(pos) != current)
+ {
+ logger->assertLog("VirtFs::rwops_seek: "
+ "Can't fit current file position in an int!");
+ return -1;
+ }
+
+ if (offset == 0) /* this is a "tell" call. We're done. */
+ return pos;
+
+ pos += offset;
+ }
+ else if (whence == SEEK_END)
+ {
+ const int64_t len = VirtFs::fileLength(handle);
+ if (len == -1)
+ {
+ logger->assertLog(
+ "VirtFs::rwops_seek:Can't find end of file.");
+ return -1;
+ }
+
+ pos = static_cast<RWOPSINT>(len);
+ if (static_cast<int64_t>(pos) != len)
+ {
+ logger->assertLog("VirtFs::rwops_seek: "
+ "Can't fit end-of-file position in an int!");
+ return -1;
+ }
+
+ pos += offset;
+ }
+ else
+ {
+ logger->assertLog(
+ "VirtFs::rwops_seek: Invalid 'whence' parameter.");
+ return -1;
+ }
+
+ if (pos < 0)
+ {
+ logger->assertLog("VirtFs::rwops_seek: "
+ "Attempt to seek past start of file.");
+ return -1;
+ }
+
+ if (!VirtFs::seek(handle, static_cast<uint64_t>(pos)))
+ {
+ logger->assertLog("VirtFs::rwops_seek: seek error.");
+ return -1;
+ }
+
+ return pos;
+ }
+
+ RWOPSSIZE rwops_read(SDL_RWops *const rw,
+ void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE maxnum)
+ {
+ if (!rw)
+ return 0;
+ VirtFile *const handle = static_cast<VirtFile *const>(
+ rw->hidden.unknown.data1);
+ const int64_t rc = VirtFs::read(handle, ptr,
+ CAST_U32(size),
+ CAST_U32(maxnum));
+ if (rc != static_cast<int64_t>(maxnum))
+ {
+ if (!VirtFs::eof(handle)) /* not EOF? Must be an error. */
+ {
+ logger->assertLog("VirtFs::rwops_seek: read error.");
+ }
+ }
+
+ return CAST_S32(rc);
+ }
+
+ RWOPSSIZE rwops_write(SDL_RWops *const rw,
+ const void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE num)
+ {
+ if (!rw)
+ return 0;
+ VirtFile *const handle = static_cast<VirtFile *const>(
+ rw->hidden.unknown.data1);
+ const int64_t rc = VirtFs::write(handle, ptr,
+ CAST_U32(size),
+ CAST_U32(num));
+ if (rc != static_cast<int64_t>(num))
+ {
+ logger->assertLog("VirtFs::rwops_seek: write error.");
+ }
+
+ return CAST_S32(rc);
+ }
+
+ int rwops_close(SDL_RWops *const rw)
+ {
+ if (!rw)
+ return 0;
+ VirtFile *const handle = static_cast<VirtFile*>(
+ rw->hidden.unknown.data1);
+ if (!VirtFs::close(handle))
+ {
+ logger->assertLog("VirtFs::rwops_seek: close error.");
+ return -1;
+ }
+
+ SDL_FreeRW(rw);
+ return 0;
+ }
+
+#ifdef USE_SDL2
+ RWOPSINT rwops_size(SDL_RWops *const rw)
+ {
+ VirtFile *const handle = static_cast<VirtFile *const>(
+ rw->hidden.unknown.data1);
+ return VirtFs::fileLength(handle);
+ }
+#endif // USE_SDL2
+
+} // namespace VirtFsZip
diff --git a/src/fs/virtfs/virtfsziprwops.h b/src/fs/virtfs/virtfsziprwops.h
new file mode 100644
index 000000000..4748cc875
--- /dev/null
+++ b/src/fs/virtfs/virtfsziprwops.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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UTILS_VIRTFS_VIRTFSZIPRWOPS_H
+#define UTILS_VIRTFS_VIRTFSZIPRWOPS_H
+
+#include "fs/virtfs/rwopstypes.h"
+
+#include "localconsts.h"
+
+struct SDL_RWops;
+
+namespace VirtFsZip
+{
+ RWOPSINT rwops_seek(SDL_RWops *const rw,
+ const RWOPSINT offset,
+ const int whence);
+ RWOPSSIZE rwops_read(SDL_RWops *const rw,
+ void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE maxnum);
+ RWOPSSIZE rwops_write(SDL_RWops *const rw,
+ const void *const ptr,
+ const RWOPSSIZE size,
+ const RWOPSSIZE num);
+ int rwops_close(SDL_RWops *const rw);
+#ifdef USE_SDL2
+ RWOPSINT rwops_size(SDL_RWops *const rw);
+#endif // USE_SDL2
+
+} // namespace VirtFsZip
+
+#endif // UTILS_VIRTFS_VIRTFSZIPRWOPS_H