aboutsummaryrefslogtreecommitdiff
path: root/backends/saves
diff options
context:
space:
mode:
authorAlexander Tkachev2016-06-18 19:35:57 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commit65e87c6c70fc1e5af8f0c3fb762ca13e6aa6a8e4 (patch)
treee209c6d22539fedd3456f954394c2d6cf73113cb /backends/saves
parentaee713141b3a401f08e63cd9ccf5ce3dfe1cb06e (diff)
downloadscummvm-rg350-65e87c6c70fc1e5af8f0c3fb762ca13e6aa6a8e4.tar.gz
scummvm-rg350-65e87c6c70fc1e5af8f0c3fb762ca13e6aa6a8e4.tar.bz2
scummvm-rg350-65e87c6c70fc1e5af8f0c3fb762ca13e6aa6a8e4.zip
CLOUD: Update save's timestamp on rewrite
This commit moves save/load timestamps static methods into DefaultSaveFileManager and fixes a few related bugs.
Diffstat (limited to 'backends/saves')
-rw-r--r--backends/saves/default/default-saves.cpp109
-rw-r--r--backends/saves/default/default-saves.h14
2 files changed, 122 insertions, 1 deletions
diff --git a/backends/saves/default/default-saves.cpp b/backends/saves/default/default-saves.cpp
index e20ce31d18..54dc1c2966 100644
--- a/backends/saves/default/default-saves.cpp
+++ b/backends/saves/default/default-saves.cpp
@@ -29,6 +29,7 @@
#ifdef USE_CLOUD
#include "backends/cloud/cloudmanager.h"
+#include "common/file.h"
#endif
#if !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
@@ -46,6 +47,10 @@
#include <errno.h> // for removeSavefile()
#endif
+#ifdef USE_CLOUD
+const char *DefaultSaveFileManager::TIMESTAMPS_FILENAME = "timestamps";
+#endif
+
DefaultSaveFileManager::DefaultSaveFileManager() {
}
@@ -142,6 +147,13 @@ Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const Common::String
}
}
+#ifdef USE_CLOUD
+ // Update file's timestamp
+ Common::HashMap<Common::String, uint32> timestamps = loadTimestamps();
+ timestamps[filename] = INVALID_TIMESTAMP;
+ saveTimestamps(timestamps);
+#endif
+
// Obtain node.
SaveFileCache::const_iterator file = _saveFileCache.find(filename);
Common::FSNode fileNode;
@@ -266,4 +278,101 @@ void DefaultSaveFileManager::assureCached(const Common::String &savePathName) {
_cachedDirectory = savePathName;
}
+#ifdef USE_CLOUD
+
+Common::HashMap<Common::String, uint32> DefaultSaveFileManager::loadTimestamps() {
+ Common::HashMap<Common::String, uint32> timestamps;
+
+ //refresh the files list
+ Common::Array<Common::String> files;
+ g_system->getSavefileManager()->updateSavefilesList(files);
+
+ //start with listing all the files in saves/ directory and setting invalid timestamp to them
+ Common::StringArray localFiles = g_system->getSavefileManager()->listSavefiles("*");
+ for (uint32 i = 0; i < localFiles.size(); ++i)
+ timestamps[localFiles[i]] = INVALID_TIMESTAMP;
+
+ //now actually load timestamps from file
+ Common::InSaveFile *file = g_system->getSavefileManager()->openRawFile(TIMESTAMPS_FILENAME);
+ if (!file) {
+ warning("DefaultSaveFileManager: failed to open '%s' file to load timestamps", TIMESTAMPS_FILENAME);
+ return timestamps;
+ }
+
+ while (!file->eos()) {
+ //read filename into buffer (reading until the first ' ')
+ Common::String buffer;
+ while (!file->eos()) {
+ byte b = file->readByte();
+ if (b == ' ') break;
+ buffer += (char)b;
+ }
+
+ //read timestamp info buffer (reading until ' ' or some line ending char)
+ Common::String filename = buffer;
+ while (true) {
+ bool lineEnded = false;
+ buffer = "";
+ while (!file->eos()) {
+ byte b = file->readByte();
+ if (b == ' ' || b == '\n' || b == '\r') {
+ lineEnded = (b == '\n');
+ break;
+ }
+ buffer += (char)b;
+ }
+
+ if (buffer == "" && file->eos()) break;
+ if (!lineEnded) filename += " " + buffer;
+ else break;
+ }
+
+ //parse timestamp
+ uint32 timestamp = buffer.asUint64();
+ if (buffer == "" || timestamp == 0) break;
+ timestamps[filename] = timestamp;
+ }
+
+ delete file;
+ return timestamps;
+}
+
+void DefaultSaveFileManager::saveTimestamps(Common::HashMap<Common::String, uint32> &timestamps) {
+ Common::DumpFile f;
+ Common::String filename = concatWithSavesPath(TIMESTAMPS_FILENAME);
+ if (!f.open(filename, true)) {
+ warning("DefaultSaveFileManager: failed to open '%s' file to save timestamps", filename.c_str());
+ return;
+ }
+
+ for (Common::HashMap<Common::String, uint32>::iterator i = timestamps.begin(); i != timestamps.end(); ++i) {
+ Common::String data = i->_key + Common::String::format(" %u\n", i->_value);
+ if (f.write(data.c_str(), data.size()) != data.size()) {
+ warning("DefaultSaveFileManager: failed to write timestamps data into '%s'", filename.c_str());
+ return;
+ }
+ }
+
+ f.flush();
+ f.finalize();
+ f.close();
+}
+
+Common::String DefaultSaveFileManager::concatWithSavesPath(Common::String name) {
+ Common::String path = ConfMan.get("savepath");
+ if (path.size() > 0 && (path.lastChar() == '/' || path.lastChar() == '\\'))
+ return path + name;
+
+ //simple heuristic to determine which path separator to use
+ int backslashes = 0;
+ for (uint32 i = 0; i < path.size(); ++i)
+ if (path[i] == '/') --backslashes;
+ else if (path[i] == '\\') ++backslashes;
+
+ if (backslashes) return path + '\\' + name;
+ return path + '/' + name;
+}
+
+#endif // ifdef USE_CLOUD
+
#endif // !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
diff --git a/backends/saves/default/default-saves.h b/backends/saves/default/default-saves.h
index af30cf45e9..e9edfb1f36 100644
--- a/backends/saves/default/default-saves.h
+++ b/backends/saves/default/default-saves.h
@@ -27,7 +27,8 @@
#include "common/savefile.h"
#include "common/str.h"
#include "common/fs.h"
-#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include <limits.h>
/**
* Provides a default savefile manager implementation for common platforms.
@@ -44,6 +45,17 @@ public:
virtual Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true);
virtual bool removeSavefile(const Common::String &filename);
+#ifdef USE_CLOUD
+
+ static const uint32 INVALID_TIMESTAMP = UINT_MAX;
+ static const char *TIMESTAMPS_FILENAME;
+
+ static Common::HashMap<Common::String, uint32> loadTimestamps();
+ static void saveTimestamps(Common::HashMap<Common::String, uint32> &timestamps);
+ static Common::String concatWithSavesPath(Common::String name);
+
+#endif
+
protected:
/**
* Get the path to the savegame directory.