aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/savefile.cpp84
-rw-r--r--common/savefile.h32
2 files changed, 77 insertions, 39 deletions
diff --git a/common/savefile.cpp b/common/savefile.cpp
index 5124ef8958..4378ce89dd 100644
--- a/common/savefile.cpp
+++ b/common/savefile.cpp
@@ -64,7 +64,7 @@ const char *SaveFileManager::getSavePath() const {
#endif
}
-class StdioSaveFile : public SaveFile {
+class StdioSaveFile : public InSaveFile, public OutSaveFile {
private:
FILE *fh;
public:
@@ -83,31 +83,47 @@ public:
bool isOpen() const { return fh != 0; }
uint32 read(void *dataPtr, uint32 dataSize) {
- return ::fread(dataPtr, 1, dataSize, fh);
+ assert(fh);
+ return fread(dataPtr, 1, dataSize, fh);
}
uint32 write(const void *dataPtr, uint32 dataSize) {
- return ::fwrite(dataPtr, 1, dataSize, fh);
+ assert(fh);
+ return fwrite(dataPtr, 1, dataSize, fh);
}
- void skip(uint32 offset) {
- ::fseek(fh, offset, SEEK_CUR);
+ uint32 pos() const {
+ assert(fh);
+ return ftell(fh);
+ }
+ uint32 size() const {
+ assert(fh);
+ uint32 oldPos = ftell(fh);
+ fseek(fh, 0, SEEK_END);
+ uint32 length = ftell(fh);
+ fseek(fh, oldPos, SEEK_SET);
+ return length;
+ }
+
+ void seek(int32 offs, int whence = SEEK_SET) {
+ assert(fh);
+ fseek(fh, offs, whence);
}
};
#ifdef USE_ZLIB
-class GzipSaveFile : public SaveFile {
+class GzipSaveFile : public InSaveFile, public OutSaveFile {
private:
gzFile fh;
bool _ioError;
public:
GzipSaveFile(const char *filename, bool saveOrLoad) {
_ioError = false;
- fh = ::gzopen(filename, (saveOrLoad? "wb" : "rb"));
+ fh = gzopen(filename, (saveOrLoad? "wb" : "rb"));
}
~GzipSaveFile() {
if (fh)
- ::gzclose(fh);
+ gzclose(fh);
}
bool eos() const { return gzeof(fh) != 0; }
@@ -117,12 +133,14 @@ public:
bool isOpen() const { return fh != 0; }
uint32 read(void *dataPtr, uint32 dataSize) {
- int ret = ::gzread(fh, dataPtr, dataSize);
+ assert(fh);
+ int ret = gzread(fh, dataPtr, dataSize);
if (ret <= -1)
_ioError = true;
return ret;
}
uint32 write(const void *dataPtr, uint32 dataSize) {
+ assert(fh);
// Due to a "bug" in the zlib headers (or maybe I should say,
// a bug in the C++ spec? Whatever <g>) we have to be a bit
// hackish here and remove the const qualifier.
@@ -130,14 +148,28 @@ public:
// which you might think is the same as "const void *" but it
// is not - rather it is equal to "void const *" which is the
// same as "void *". Hrmpf
- int ret = ::gzwrite(fh, const_cast<void *>(dataPtr), dataSize);
+ int ret = gzwrite(fh, const_cast<void *>(dataPtr), dataSize);
if (ret <= 0)
_ioError = true;
return ret;
}
- void skip(uint32 offset) {
- ::gzseek(fh, offset, SEEK_CUR);
+ uint32 pos() const {
+ assert(fh);
+ return gztell(fh);
+ }
+ uint32 size() const {
+ assert(fh);
+ uint32 oldPos = gztell(fh);
+ gzseek(fh, 0, SEEK_END);
+ uint32 length = gztell(fh);
+ gzseek(fh, oldPos, SEEK_SET);
+ return length;
+ }
+
+ void seek(int32 offs, int whence = SEEK_SET) {
+ assert(fh);
+ gzseek(fh, offs, whence);
}
};
#endif
@@ -172,25 +204,30 @@ static void join_paths(const char *filename, const char *directory,
OutSaveFile *DefaultSaveFileManager::openForSaving(const char *filename) {
char buf[256];
join_paths(filename, getSavePath(), buf, sizeof(buf));
- return makeSaveFile(buf, true);
+
+#ifdef USE_ZLIB
+ GzipSaveFile *sf = new GzipSaveFile(filename, true);
+#else
+ StdioSaveFile *sf = new StdioSaveFile(filename, true);
+#endif
+
+ if (!sf->isOpen()) {
+ delete sf;
+ sf = 0;
+ }
+ return sf;
}
InSaveFile *DefaultSaveFileManager::openForLoading(const char *filename) {
char buf[256];
join_paths(filename, getSavePath(), buf, sizeof(buf));
- return makeSaveFile(buf, false);
-}
-
-void DefaultSaveFileManager::listSavefiles(const char * /* prefix */, bool *marks, int num) {
- memset(marks, true, num * sizeof(bool));
-}
-SaveFile *DefaultSaveFileManager::makeSaveFile(const char *filename, bool saveOrLoad) {
#ifdef USE_ZLIB
- GzipSaveFile *sf = new GzipSaveFile(filename, saveOrLoad);
+ GzipSaveFile *sf = new GzipSaveFile(filename, false);
#else
- StdioSaveFile *sf = new StdioSaveFile(filename, saveOrLoad);
+ StdioSaveFile *sf = new StdioSaveFile(filename, false);
#endif
+
if (!sf->isOpen()) {
delete sf;
sf = 0;
@@ -198,5 +235,8 @@ SaveFile *DefaultSaveFileManager::makeSaveFile(const char *filename, bool saveOr
return sf;
}
+void DefaultSaveFileManager::listSavefiles(const char * /* prefix */, bool *marks, int num) {
+ memset(marks, true, num * sizeof(bool));
+}
} // End of namespace Common
diff --git a/common/savefile.h b/common/savefile.h
index af9afbb72e..d85d03268c 100644
--- a/common/savefile.h
+++ b/common/savefile.h
@@ -34,14 +34,7 @@ namespace Common {
* That typically means "save games", but also includes things like the
* IQ points in Indy3.
*/
-class InSaveFile : public Common::ReadStream {
-public:
- virtual ~InSaveFile() {}
-
- /**
- * Skip over the specified (positive) amount of bytes in the input stream.
- */
- virtual void skip(uint32 offset) = 0;
+class InSaveFile : public SeekableReadStream {
};
/**
@@ -49,9 +42,7 @@ public:
* That typically means "save games", but also includes things like the
* IQ points in Indy3.
*/
-class OutSaveFile : public Common::WriteStream {
-public:
- virtual ~OutSaveFile() {}
+class OutSaveFile : public WriteStream {
};
/**
@@ -69,20 +60,30 @@ public:
/**
* Open the file with name filename in the given directory for saving.
* @param filename the filename
- * @return pointer to a SaveFile object, or NULL if an error occured.
+ * @return pointer to an OutSaveFile, or NULL if an error occured.
*/
virtual OutSaveFile *openForSaving(const char *filename) = 0;
/**
* Open the file with name filename in the given directory for loading.
* @param filename the filename
- * @return pointer to a SaveFile object, or NULL if an error occured.
+ * @return pointer to an InSaveFile, or NULL if an error occured.
*/
virtual InSaveFile *openForLoading(const char *filename) = 0;
+ /**
+ * Request a list of available savegames with a given prefix.
+ * TODO: Document this better!
+ * TODO: Or even replace it with a better API. For example, one that
+ * returns a list of strings for all present file names.
+ */
virtual void listSavefiles(const char * /* prefix */, bool *marks, int num) = 0;
- /** Get the path to the save game directory. */
+ /**
+ * Get the path to the save game directory.
+ * Should only be used for error messages, and not to construct file paths
+ * from it, since that is highl unportable.
+ */
virtual const char *getSavePath() const;
};
@@ -91,9 +92,6 @@ public:
virtual OutSaveFile *openForSaving(const char *filename);
virtual InSaveFile *openForLoading(const char *filename);
virtual void listSavefiles(const char * /* prefix */, bool *marks, int num);
-
-protected:
- SaveFile *makeSaveFile(const char *filename, bool saveOrLoad);
};
} // End of namespace Common