MCPcopy Create free account
hub / github.com/OpenApoc/OpenApoc / writeArchiveWithBackup

Function writeArchiveWithBackup

game/state/savemanager.cpp:85–160  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

83}
84
85bool writeArchiveWithBackup(SerializationArchive *archive, const UString &path, bool pack)
86{
87 fs::path savePath = path;
88 fs::path tempPath;
89 bool shouldCleanup = false;
90 try
91 {
92 if (!fs::exists(savePath))
93 {
94 return archive->write(path, pack);
95 }
96
97 // WARNING! Dragons live here! Specifically dragon named miniz who hates windows paths
98 // (or paths not starting with dot)
99 // therefore I'm doing gymnastics here to backup and still pass original path string to
100 // archive write
101 // that is really bad, because if user clicks exit, save will be renamed to some random
102 // junk
103 // however it will still function as regular save file, so maybe not that bad?
104 fs::path saveDirectory = savePath.parent_path();
105 bool haveNewName = false;
106 for (int retries = 5; retries > 0; retries--)
107 {
108 {
109 tempPath = saveDirectory /
110 (boost::uuids::to_string(uuids::random_generator()()) + ".save");
111 if (!fs::exists(tempPath))
112 {
113 haveNewName = true;
114 break;
115 }
116 }
117 }
118
119 if (!haveNewName)
120 {
121 LogError("Unable to create temporary file at \"%s\"", tempPath.string());
122 return false;
123 }
124
125 fs::rename(savePath, tempPath);
126 shouldCleanup = true;
127 bool saveSuccess = archive->write(path, pack);
128 shouldCleanup = false;
129
130 if (saveSuccess)
131 {
132 fs::remove_all(tempPath);
133 return true;
134 }
135 else
136 {
137 if (fs::exists(savePath))
138 {
139 fs::remove_all(savePath);
140 }
141
142 fs::rename(tempPath, savePath);

Callers 1

saveGameMethod · 0.85

Calls 1

writeMethod · 0.80

Tested by

no test coverage detected