diff options
-rw-r--r-- | common/savefile.cpp | 84 | ||||
-rw-r--r-- | common/savefile.h | 32 |
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 |