| 159 | |
| 160 | template<typename T> |
| 161 | void saveObject(const char* prefix, T* obj, void (Writer::*writeMember)(std::ofstream&, T*)) { |
| 162 | if (!obj->version()) |
| 163 | obj->incrementVersion(); |
| 164 | |
| 165 | ObjVersions& versions = m_objVersions[obj->id()]; |
| 166 | if (versions.newer() == obj->version()) |
| 167 | return; |
| 168 | |
| 169 | std::string fn = prefix; |
| 170 | fn.push_back('-'); |
| 171 | fn += base::convert_to<std::string>(obj->id()); |
| 172 | |
| 173 | std::string fullfn = base::join_path(m_dir, fn); |
| 174 | std::string oldfn = fullfn + "." + base::convert_to<std::string>(versions.older()); |
| 175 | fullfn += "." + base::convert_to<std::string>(obj->version()); |
| 176 | |
| 177 | std::ofstream s(FSTREAM_PATH(fullfn), std::ofstream::binary); |
| 178 | write32(s, 0); // Leave a room for the magic number |
| 179 | (this->*writeMember)(s, obj); // Write the object |
| 180 | |
| 181 | // Flush all data. In this way we ensure that the magic number is |
| 182 | // the last thing being written in the file. |
| 183 | s.flush(); |
| 184 | |
| 185 | // Write the magic number |
| 186 | s.seekp(0); |
| 187 | write32(s, MAGIC_NUMBER); |
| 188 | |
| 189 | // Remove the older version |
| 190 | try { |
| 191 | if (versions.older() && base::is_file(oldfn)) |
| 192 | base::delete_file(oldfn); |
| 193 | } |
| 194 | catch (const std::exception&) { |
| 195 | TRACE(" - Cannot delete %s #%d v%d\n", prefix, obj->id(), versions.older()); |
| 196 | } |
| 197 | |
| 198 | // Rotate versions and add the latest one |
| 199 | versions.rotateRevisions(obj->version()); |
| 200 | |
| 201 | TRACE(" - Saved %s #%d v%d\n", prefix, obj->id(), obj->version()); |
| 202 | } |
| 203 | |
| 204 | std::string m_dir; |
| 205 | app::Document* m_doc; |
nothing calls this directly
no test coverage detected