summaryrefslogtreecommitdiff
path: root/src/common/chunk_file.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/common/chunk_file.h539
1 files changed, 256 insertions, 283 deletions
diff --git a/src/common/chunk_file.h b/src/common/chunk_file.h
index 1e1bcff31..3b36c0a9e 100644
--- a/src/common/chunk_file.h
+++ b/src/common/chunk_file.h
@@ -41,81 +41,86 @@
41#include "common/logging/log.h" 41#include "common/logging/log.h"
42 42
43template <class T> 43template <class T>
44struct LinkedListItem : public T 44struct LinkedListItem : public T {
45{ 45 LinkedListItem<T>* next;
46 LinkedListItem<T> *next;
47}; 46};
48 47
49class PointerWrap; 48class PointerWrap;
50 49
51class PointerWrapSection 50class PointerWrapSection {
52{
53public: 51public:
54 PointerWrapSection(PointerWrap &p, int ver, const char *title) : p_(p), ver_(ver), title_(title) { 52 PointerWrapSection(PointerWrap& p, int ver, const char* title)
53 : p_(p), ver_(ver), title_(title) {
55 } 54 }
56 ~PointerWrapSection(); 55 ~PointerWrapSection();
57 56
58 bool operator == (const int &v) const { return ver_ == v; } 57 bool operator==(const int& v) const {
59 bool operator != (const int &v) const { return ver_ != v; } 58 return ver_ == v;
60 bool operator <= (const int &v) const { return ver_ <= v; } 59 }
61 bool operator >= (const int &v) const { return ver_ >= v; } 60 bool operator!=(const int& v) const {
62 bool operator < (const int &v) const { return ver_ < v; } 61 return ver_ != v;
63 bool operator > (const int &v) const { return ver_ > v; } 62 }
63 bool operator<=(const int& v) const {
64 return ver_ <= v;
65 }
66 bool operator>=(const int& v) const {
67 return ver_ >= v;
68 }
69 bool operator<(const int& v) const {
70 return ver_ < v;
71 }
72 bool operator>(const int& v) const {
73 return ver_ > v;
74 }
64 75
65 operator bool() const { 76 operator bool() const {
66 return ver_ > 0; 77 return ver_ > 0;
67 } 78 }
68 79
69private: 80private:
70 PointerWrap &p_; 81 PointerWrap& p_;
71 int ver_; 82 int ver_;
72 const char *title_; 83 const char* title_;
73}; 84};
74 85
75// Wrapper class 86// Wrapper class
76class PointerWrap 87class PointerWrap {
77{ 88// This makes it a compile error if you forget to define DoState() on non-POD.
78 // This makes it a compile error if you forget to define DoState() on non-POD. 89// Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason...
79 // Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason...
80#ifdef _MSC_VER 90#ifdef _MSC_VER
81 template<typename T, bool isPOD = std::is_pod<T>::value, bool isPointer = std::is_pointer<T>::value> 91 template <typename T, bool isPOD = std::is_pod<T>::value,
92 bool isPointer = std::is_pointer<T>::value>
82#else 93#else
83 template<typename T, bool isPOD = __is_pod(T), bool isPointer = std::is_pointer<T>::value> 94 template <typename T, bool isPOD = __is_pod(T), bool isPointer = std::is_pointer<T>::value>
84#endif 95#endif
85 struct DoHelper 96 struct DoHelper {
86 { 97 static void DoArray(PointerWrap* p, T* x, int count) {
87 static void DoArray(PointerWrap *p, T *x, int count)
88 {
89 for (int i = 0; i < count; ++i) 98 for (int i = 0; i < count; ++i)
90 p->Do(x[i]); 99 p->Do(x[i]);
91 } 100 }
92 101
93 static void Do(PointerWrap *p, T &x) 102 static void Do(PointerWrap* p, T& x) {
94 {
95 p->DoClass(x); 103 p->DoClass(x);
96 } 104 }
97 }; 105 };
98 106
99 template<typename T> 107 template <typename T>
100 struct DoHelper<T, true, false> 108 struct DoHelper<T, true, false> {
101 { 109 static void DoArray(PointerWrap* p, T* x, int count) {
102 static void DoArray(PointerWrap *p, T *x, int count) 110 p->DoVoid((void*)x, sizeof(T) * count);
103 {
104 p->DoVoid((void *)x, sizeof(T) * count);
105 } 111 }
106 112
107 static void Do(PointerWrap *p, T &x) 113 static void Do(PointerWrap* p, T& x) {
108 { 114 p->DoVoid((void*)&x, sizeof(x));
109 p->DoVoid((void *)&x, sizeof(x));
110 } 115 }
111 }; 116 };
112 117
113public: 118public:
114 enum Mode { 119 enum Mode {
115 MODE_READ = 1, // load 120 MODE_READ = 1, // load
116 MODE_WRITE, // save 121 MODE_WRITE, // save
117 MODE_MEASURE, // calculate size 122 MODE_MEASURE, // calculate size
118 MODE_VERIFY, // compare 123 MODE_VERIFY, // compare
119 }; 124 };
120 125
121 enum Error { 126 enum Error {
@@ -124,247 +129,239 @@ public:
124 ERROR_FAILURE = 2, 129 ERROR_FAILURE = 2,
125 }; 130 };
126 131
127 u8 **ptr; 132 u8** ptr;
128 Mode mode; 133 Mode mode;
129 Error error; 134 Error error;
130 135
131public: 136public:
132 PointerWrap(u8 **ptr_, Mode mode_) : ptr(ptr_), mode(mode_), error(ERROR_NONE) {} 137 PointerWrap(u8** ptr_, Mode mode_) : ptr(ptr_), mode(mode_), error(ERROR_NONE) {
133 PointerWrap(unsigned char **ptr_, int mode_) : ptr((u8**)ptr_), mode((Mode)mode_), error(ERROR_NONE) {} 138 }
139 PointerWrap(unsigned char** ptr_, int mode_)
140 : ptr((u8**)ptr_), mode((Mode)mode_), error(ERROR_NONE) {
141 }
134 142
135 PointerWrapSection Section(const char *title, int ver) { 143 PointerWrapSection Section(const char* title, int ver) {
136 return Section(title, ver, ver); 144 return Section(title, ver, ver);
137 } 145 }
138 146
139 // The returned object can be compared against the version that was loaded. 147 // The returned object can be compared against the version that was loaded.
140 // This can be used to support versions as old as minVer. 148 // This can be used to support versions as old as minVer.
141 // Version = 0 means the section was not found. 149 // Version = 0 means the section was not found.
142 PointerWrapSection Section(const char *title, int minVer, int ver) { 150 PointerWrapSection Section(const char* title, int minVer, int ver) {
143 char marker[16] = {0}; 151 char marker[16] = {0};
144 int foundVersion = ver; 152 int foundVersion = ver;
145 153
146 strncpy(marker, title, sizeof(marker)); 154 strncpy(marker, title, sizeof(marker));
147 if (!ExpectVoid(marker, sizeof(marker))) 155 if (!ExpectVoid(marker, sizeof(marker))) {
148 {
149 // Might be before we added name markers for safety. 156 // Might be before we added name markers for safety.
150 if (foundVersion == 1 && ExpectVoid(&foundVersion, sizeof(foundVersion))) 157 if (foundVersion == 1 && ExpectVoid(&foundVersion, sizeof(foundVersion)))
151 DoMarker(title); 158 DoMarker(title);
152 // Wasn't found, but maybe we can still load the state. 159 // Wasn't found, but maybe we can still load the state.
153 else 160 else
154 foundVersion = 0; 161 foundVersion = 0;
155 } 162 } else
156 else
157 Do(foundVersion); 163 Do(foundVersion);
158 164
159 if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { 165 if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) {
160 LOG_ERROR(Common, "Savestate failure: wrong version %d found for %s", foundVersion, title); 166 LOG_ERROR(Common, "Savestate failure: wrong version %d found for %s", foundVersion,
167 title);
161 SetError(ERROR_FAILURE); 168 SetError(ERROR_FAILURE);
162 return PointerWrapSection(*this, -1, title); 169 return PointerWrapSection(*this, -1, title);
163 } 170 }
164 return PointerWrapSection(*this, foundVersion, title); 171 return PointerWrapSection(*this, foundVersion, title);
165 } 172 }
166 173
167 void SetMode(Mode mode_) {mode = mode_;} 174 void SetMode(Mode mode_) {
168 Mode GetMode() const {return mode;} 175 mode = mode_;
169 u8 **GetPPtr() {return ptr;} 176 }
170 void SetError(Error error_) 177 Mode GetMode() const {
171 { 178 return mode;
179 }
180 u8** GetPPtr() {
181 return ptr;
182 }
183 void SetError(Error error_) {
172 if (error < error_) 184 if (error < error_)
173 error = error_; 185 error = error_;
174 if (error > ERROR_WARNING) 186 if (error > ERROR_WARNING)
175 mode = PointerWrap::MODE_MEASURE; 187 mode = PointerWrap::MODE_MEASURE;
176 } 188 }
177 189
178 bool ExpectVoid(void *data, int size) 190 bool ExpectVoid(void* data, int size) {
179 {
180 switch (mode) { 191 switch (mode) {
181 case MODE_READ: if (memcmp(data, *ptr, size) != 0) return false; break; 192 case MODE_READ:
182 case MODE_WRITE: memcpy(*ptr, data, size); break; 193 if (memcmp(data, *ptr, size) != 0)
183 case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything 194 return false;
195 break;
196 case MODE_WRITE:
197 memcpy(*ptr, data, size);
198 break;
199 case MODE_MEASURE:
200 break; // MODE_MEASURE - don't need to do anything
184 case MODE_VERIFY: 201 case MODE_VERIFY:
185 for (int i = 0; i < size; i++) { 202 for (int i = 0; i < size; i++) {
186 DEBUG_ASSERT_MSG(((u8*)data)[i] == (*ptr)[i], 203 DEBUG_ASSERT_MSG(
204 ((u8*)data)[i] == (*ptr)[i],
187 "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", 205 "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n",
188 ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], 206 ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i],
189 (*ptr)[i], (*ptr)[i], &(*ptr)[i]); 207 &(*ptr)[i]);
190 } 208 }
191 break; 209 break;
192 default: break; // throw an error? 210 default:
211 break; // throw an error?
193 } 212 }
194 (*ptr) += size; 213 (*ptr) += size;
195 return true; 214 return true;
196 } 215 }
197 216
198 void DoVoid(void *data, int size) 217 void DoVoid(void* data, int size) {
199 {
200 switch (mode) { 218 switch (mode) {
201 case MODE_READ: memcpy(data, *ptr, size); break; 219 case MODE_READ:
202 case MODE_WRITE: memcpy(*ptr, data, size); break; 220 memcpy(data, *ptr, size);
203 case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything 221 break;
222 case MODE_WRITE:
223 memcpy(*ptr, data, size);
224 break;
225 case MODE_MEASURE:
226 break; // MODE_MEASURE - don't need to do anything
204 case MODE_VERIFY: 227 case MODE_VERIFY:
205 for (int i = 0; i < size; i++) { 228 for (int i = 0; i < size; i++) {
206 DEBUG_ASSERT_MSG(((u8*)data)[i] == (*ptr)[i], 229 DEBUG_ASSERT_MSG(
230 ((u8*)data)[i] == (*ptr)[i],
207 "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", 231 "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n",
208 ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], 232 ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i],
209 (*ptr)[i], (*ptr)[i], &(*ptr)[i]); 233 &(*ptr)[i]);
210 } 234 }
211 break; 235 break;
212 default: break; // throw an error? 236 default:
237 break; // throw an error?
213 } 238 }
214 (*ptr) += size; 239 (*ptr) += size;
215 } 240 }
216 241
217 template<class K, class T> 242 template <class K, class T>
218 void Do(std::map<K, T *> &x) 243 void Do(std::map<K, T*>& x) {
219 { 244 if (mode == MODE_READ) {
220 if (mode == MODE_READ) 245 for (auto it = x.begin(), end = x.end(); it != end; ++it) {
221 {
222 for (auto it = x.begin(), end = x.end(); it != end; ++it)
223 {
224 if (it->second != nullptr) 246 if (it->second != nullptr)
225 delete it->second; 247 delete it->second;
226 } 248 }
227 } 249 }
228 T *dv = nullptr; 250 T* dv = nullptr;
229 DoMap(x, dv); 251 DoMap(x, dv);
230 } 252 }
231 253
232 template<class K, class T> 254 template <class K, class T>
233 void Do(std::map<K, T> &x) 255 void Do(std::map<K, T>& x) {
234 {
235 T dv = T(); 256 T dv = T();
236 DoMap(x, dv); 257 DoMap(x, dv);
237 } 258 }
238 259
239 template<class K, class T> 260 template <class K, class T>
240 void DoMap(std::map<K, T> &x, T &default_val) 261 void DoMap(std::map<K, T>& x, T& default_val) {
241 {
242 unsigned int number = (unsigned int)x.size(); 262 unsigned int number = (unsigned int)x.size();
243 Do(number); 263 Do(number);
244 switch (mode) { 264 switch (mode) {
245 case MODE_READ: 265 case MODE_READ: {
246 { 266 x.clear();
247 x.clear(); 267 while (number > 0) {
248 while (number > 0) 268 K first = K();
249 { 269 Do(first);
250 K first = K(); 270 T second = default_val;
251 Do(first); 271 Do(second);
252 T second = default_val; 272 x[first] = second;
253 Do(second); 273 --number;
254 x[first] = second;
255 --number;
256 }
257 } 274 }
258 break; 275 } break;
259 case MODE_WRITE: 276 case MODE_WRITE:
260 case MODE_MEASURE: 277 case MODE_MEASURE:
261 case MODE_VERIFY: 278 case MODE_VERIFY: {
262 { 279 typename std::map<K, T>::iterator itr = x.begin();
263 typename std::map<K, T>::iterator itr = x.begin(); 280 while (number > 0) {
264 while (number > 0) 281 K first = itr->first;
265 { 282 Do(first);
266 K first = itr->first; 283 Do(itr->second);
267 Do(first); 284 --number;
268 Do(itr->second); 285 ++itr;
269 --number;
270 ++itr;
271 }
272 } 286 }
273 break; 287 } break;
274 } 288 }
275 } 289 }
276 290
277 template<class K, class T> 291 template <class K, class T>
278 void Do(std::multimap<K, T *> &x) 292 void Do(std::multimap<K, T*>& x) {
279 { 293 if (mode == MODE_READ) {
280 if (mode == MODE_READ) 294 for (auto it = x.begin(), end = x.end(); it != end; ++it) {
281 {
282 for (auto it = x.begin(), end = x.end(); it != end; ++it)
283 {
284 if (it->second != nullptr) 295 if (it->second != nullptr)
285 delete it->second; 296 delete it->second;
286 } 297 }
287 } 298 }
288 T *dv = nullptr; 299 T* dv = nullptr;
289 DoMultimap(x, dv); 300 DoMultimap(x, dv);
290 } 301 }
291 302
292 template<class K, class T> 303 template <class K, class T>
293 void Do(std::multimap<K, T> &x) 304 void Do(std::multimap<K, T>& x) {
294 {
295 T dv = T(); 305 T dv = T();
296 DoMultimap(x, dv); 306 DoMultimap(x, dv);
297 } 307 }
298 308
299 template<class K, class T> 309 template <class K, class T>
300 void DoMultimap(std::multimap<K, T> &x, T &default_val) 310 void DoMultimap(std::multimap<K, T>& x, T& default_val) {
301 {
302 unsigned int number = (unsigned int)x.size(); 311 unsigned int number = (unsigned int)x.size();
303 Do(number); 312 Do(number);
304 switch (mode) { 313 switch (mode) {
305 case MODE_READ: 314 case MODE_READ: {
306 { 315 x.clear();
307 x.clear(); 316 while (number > 0) {
308 while (number > 0) 317 K first = K();
309 { 318 Do(first);
310 K first = K(); 319 T second = default_val;
311 Do(first); 320 Do(second);
312 T second = default_val; 321 x.insert(std::make_pair(first, second));
313 Do(second); 322 --number;
314 x.insert(std::make_pair(first, second));
315 --number;
316 }
317 } 323 }
318 break; 324 } break;
319 case MODE_WRITE: 325 case MODE_WRITE:
320 case MODE_MEASURE: 326 case MODE_MEASURE:
321 case MODE_VERIFY: 327 case MODE_VERIFY: {
322 { 328 typename std::multimap<K, T>::iterator itr = x.begin();
323 typename std::multimap<K, T>::iterator itr = x.begin(); 329 while (number > 0) {
324 while (number > 0) 330 Do(itr->first);
325 { 331 Do(itr->second);
326 Do(itr->first); 332 --number;
327 Do(itr->second); 333 ++itr;
328 --number;
329 ++itr;
330 }
331 } 334 }
332 break; 335 } break;
333 } 336 }
334 } 337 }
335 338
336 // Store vectors. 339 // Store vectors.
337 template<class T> 340 template <class T>
338 void Do(std::vector<T *> &x) 341 void Do(std::vector<T*>& x) {
339 { 342 T* dv = nullptr;
340 T *dv = nullptr;
341 DoVector(x, dv); 343 DoVector(x, dv);
342 } 344 }
343 345
344 template<class T> 346 template <class T>
345 void Do(std::vector<T> &x) 347 void Do(std::vector<T>& x) {
346 {
347 T dv = T(); 348 T dv = T();
348 DoVector(x, dv); 349 DoVector(x, dv);
349 } 350 }
350 351
351 352 template <class T>
352 template<class T> 353 void DoPOD(std::vector<T>& x) {
353 void DoPOD(std::vector<T> &x)
354 {
355 T dv = T(); 354 T dv = T();
356 DoVectorPOD(x, dv); 355 DoVectorPOD(x, dv);
357 } 356 }
358 357
359 template<class T> 358 template <class T>
360 void Do(std::vector<T> &x, T &default_val) 359 void Do(std::vector<T>& x, T& default_val) {
361 {
362 DoVector(x, default_val); 360 DoVector(x, default_val);
363 } 361 }
364 362
365 template<class T> 363 template <class T>
366 void DoVector(std::vector<T> &x, T &default_val) 364 void DoVector(std::vector<T>& x, T& default_val) {
367 {
368 u32 vec_size = (u32)x.size(); 365 u32 vec_size = (u32)x.size();
369 Do(vec_size); 366 Do(vec_size);
370 x.resize(vec_size, default_val); 367 x.resize(vec_size, default_val);
@@ -372,9 +369,8 @@ public:
372 DoArray(&x[0], vec_size); 369 DoArray(&x[0], vec_size);
373 } 370 }
374 371
375 template<class T> 372 template <class T>
376 void DoVectorPOD(std::vector<T> &x, T &default_val) 373 void DoVectorPOD(std::vector<T>& x, T& default_val) {
377 {
378 u32 vec_size = (u32)x.size(); 374 u32 vec_size = (u32)x.size();
379 Do(vec_size); 375 Do(vec_size);
380 x.resize(vec_size, default_val); 376 x.resize(vec_size, default_val);
@@ -383,55 +379,48 @@ public:
383 } 379 }
384 380
385 // Store deques. 381 // Store deques.
386 template<class T> 382 template <class T>
387 void Do(std::deque<T *> &x) 383 void Do(std::deque<T*>& x) {
388 { 384 T* dv = nullptr;
389 T *dv = nullptr;
390 DoDeque(x, dv); 385 DoDeque(x, dv);
391 } 386 }
392 387
393 template<class T> 388 template <class T>
394 void Do(std::deque<T> &x) 389 void Do(std::deque<T>& x) {
395 {
396 T dv = T(); 390 T dv = T();
397 DoDeque(x, dv); 391 DoDeque(x, dv);
398 } 392 }
399 393
400 template<class T> 394 template <class T>
401 void DoDeque(std::deque<T> &x, T &default_val) 395 void DoDeque(std::deque<T>& x, T& default_val) {
402 {
403 u32 deq_size = (u32)x.size(); 396 u32 deq_size = (u32)x.size();
404 Do(deq_size); 397 Do(deq_size);
405 x.resize(deq_size, default_val); 398 x.resize(deq_size, default_val);
406 u32 i; 399 u32 i;
407 for(i = 0; i < deq_size; i++) 400 for (i = 0; i < deq_size; i++)
408 Do(x[i]); 401 Do(x[i]);
409 } 402 }
410 403
411 // Store STL lists. 404 // Store STL lists.
412 template<class T> 405 template <class T>
413 void Do(std::list<T *> &x) 406 void Do(std::list<T*>& x) {
414 { 407 T* dv = nullptr;
415 T *dv = nullptr;
416 Do(x, dv); 408 Do(x, dv);
417 } 409 }
418 410
419 template<class T> 411 template <class T>
420 void Do(std::list<T> &x) 412 void Do(std::list<T>& x) {
421 {
422 T dv = T(); 413 T dv = T();
423 DoList(x, dv); 414 DoList(x, dv);
424 } 415 }
425 416
426 template<class T> 417 template <class T>
427 void Do(std::list<T> &x, T &default_val) 418 void Do(std::list<T>& x, T& default_val) {
428 {
429 DoList(x, default_val); 419 DoList(x, default_val);
430 } 420 }
431 421
432 template<class T> 422 template <class T>
433 void DoList(std::list<T> &x, T &default_val) 423 void DoList(std::list<T>& x, T& default_val) {
434 {
435 u32 list_size = (u32)x.size(); 424 u32 list_size = (u32)x.size();
436 Do(list_size); 425 Do(list_size);
437 x.resize(list_size, default_val); 426 x.resize(list_size, default_val);
@@ -441,15 +430,11 @@ public:
441 Do(*itr); 430 Do(*itr);
442 } 431 }
443 432
444
445 // Store STL sets. 433 // Store STL sets.
446 template <class T> 434 template <class T>
447 void Do(std::set<T *> &x) 435 void Do(std::set<T*>& x) {
448 { 436 if (mode == MODE_READ) {
449 if (mode == MODE_READ) 437 for (auto it = x.begin(), end = x.end(); it != end; ++it) {
450 {
451 for (auto it = x.begin(), end = x.end(); it != end; ++it)
452 {
453 if (*it != nullptr) 438 if (*it != nullptr)
454 delete *it; 439 delete *it;
455 } 440 }
@@ -458,39 +443,31 @@ public:
458 } 443 }
459 444
460 template <class T> 445 template <class T>
461 void Do(std::set<T> &x) 446 void Do(std::set<T>& x) {
462 {
463 DoSet(x); 447 DoSet(x);
464 } 448 }
465 449
466 template <class T> 450 template <class T>
467 void DoSet(std::set<T> &x) 451 void DoSet(std::set<T>& x) {
468 {
469 unsigned int number = (unsigned int)x.size(); 452 unsigned int number = (unsigned int)x.size();
470 Do(number); 453 Do(number);
471 454
472 switch (mode) 455 switch (mode) {
473 { 456 case MODE_READ: {
474 case MODE_READ: 457 x.clear();
475 { 458 while (number-- > 0) {
476 x.clear(); 459 T it = T();
477 while (number-- > 0) 460 Do(it);
478 { 461 x.insert(it);
479 T it = T();
480 Do(it);
481 x.insert(it);
482 }
483 } 462 }
484 break; 463 } break;
485 case MODE_WRITE: 464 case MODE_WRITE:
486 case MODE_MEASURE: 465 case MODE_MEASURE:
487 case MODE_VERIFY: 466 case MODE_VERIFY: {
488 { 467 typename std::set<T>::iterator itr = x.begin();
489 typename std::set<T>::iterator itr = x.begin(); 468 while (number-- > 0)
490 while (number-- > 0) 469 Do(*itr++);
491 Do(*itr++); 470 } break;
492 }
493 break;
494 471
495 default: 472 default:
496 LOG_ERROR(Common, "Savestate error: invalid mode %d.", mode); 473 LOG_ERROR(Common, "Savestate error: invalid mode %d.", mode);
@@ -498,51 +475,58 @@ public:
498 } 475 }
499 476
500 // Store strings. 477 // Store strings.
501 void Do(std::string &x) 478 void Do(std::string& x) {
502 {
503 int stringLen = (int)x.length() + 1; 479 int stringLen = (int)x.length() + 1;
504 Do(stringLen); 480 Do(stringLen);
505 481
506 switch (mode) { 482 switch (mode) {
507 case MODE_READ: x = (char*)*ptr; break; 483 case MODE_READ:
508 case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; 484 x = (char*)*ptr;
509 case MODE_MEASURE: break; 485 break;
486 case MODE_WRITE:
487 memcpy(*ptr, x.c_str(), stringLen);
488 break;
489 case MODE_MEASURE:
490 break;
510 case MODE_VERIFY: 491 case MODE_VERIFY:
511 DEBUG_ASSERT_MSG((x == (char*)*ptr), 492 DEBUG_ASSERT_MSG((x == (char*)*ptr),
512 "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", 493 "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n",
513 x.c_str(), (char*)*ptr, ptr); 494 x.c_str(), (char*)*ptr, ptr);
514 break; 495 break;
515 } 496 }
516 (*ptr) += stringLen; 497 (*ptr) += stringLen;
517 } 498 }
518 499
519 void Do(std::wstring &x) 500 void Do(std::wstring& x) {
520 { 501 int stringLen = sizeof(wchar_t) * ((int)x.length() + 1);
521 int stringLen = sizeof(wchar_t)*((int)x.length() + 1);
522 Do(stringLen); 502 Do(stringLen);
523 503
524 switch (mode) { 504 switch (mode) {
525 case MODE_READ: x = (wchar_t*)*ptr; break; 505 case MODE_READ:
526 case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; 506 x = (wchar_t*)*ptr;
527 case MODE_MEASURE: break; 507 break;
508 case MODE_WRITE:
509 memcpy(*ptr, x.c_str(), stringLen);
510 break;
511 case MODE_MEASURE:
512 break;
528 case MODE_VERIFY: 513 case MODE_VERIFY:
529 DEBUG_ASSERT_MSG((x == (wchar_t*)*ptr), 514 DEBUG_ASSERT_MSG((x == (wchar_t*)*ptr),
530 "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", 515 "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n",
531 x.c_str(), (wchar_t*)*ptr, ptr); 516 x.c_str(), (wchar_t*)*ptr, ptr);
532 break; 517 break;
533 } 518 }
534 (*ptr) += stringLen; 519 (*ptr) += stringLen;
535 } 520 }
536 521
537 template<class T> 522 template <class T>
538 void DoClass(T &x) { 523 void DoClass(T& x) {
539 x.DoState(*this); 524 x.DoState(*this);
540 } 525 }
541 526
542 template<class T> 527 template <class T>
543 void DoClass(T *&x) { 528 void DoClass(T*& x) {
544 if (mode == MODE_READ) 529 if (mode == MODE_READ) {
545 {
546 if (x != nullptr) 530 if (x != nullptr)
547 delete x; 531 delete x;
548 x = new T(); 532 x = new T();
@@ -550,81 +534,70 @@ public:
550 x->DoState(*this); 534 x->DoState(*this);
551 } 535 }
552 536
553 template<class T> 537 template <class T>
554 void DoArray(T *x, int count) { 538 void DoArray(T* x, int count) {
555 DoHelper<T>::DoArray(this, x, count); 539 DoHelper<T>::DoArray(this, x, count);
556 } 540 }
557 541
558 template<class T> 542 template <class T>
559 void Do(T &x) { 543 void Do(T& x) {
560 DoHelper<T>::Do(this, x); 544 DoHelper<T>::Do(this, x);
561 } 545 }
562 546
563 template<class T> 547 template <class T>
564 void DoPOD(T &x) { 548 void DoPOD(T& x) {
565 DoHelper<T>::Do(this, x); 549 DoHelper<T>::Do(this, x);
566 } 550 }
567 551
568 template<class T> 552 template <class T>
569 void DoPointer(T* &x, T*const base) { 553 void DoPointer(T*& x, T* const base) {
570 // pointers can be more than 2^31 apart, but you're using this function wrong if you need that much range 554 // pointers can be more than 2^31 apart, but you're using this function wrong if you need
555 // that much range
571 s32 offset = x - base; 556 s32 offset = x - base;
572 Do(offset); 557 Do(offset);
573 if (mode == MODE_READ) 558 if (mode == MODE_READ)
574 x = base + offset; 559 x = base + offset;
575 } 560 }
576 561
577 template<class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*), void (*TDo)(PointerWrap&, T*)> 562 template <class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*),
578 void DoLinkedList(LinkedListItem<T>*& list_start, LinkedListItem<T>** list_end = nullptr) 563 void (*TDo)(PointerWrap&, T*)>
579 { 564 void DoLinkedList(LinkedListItem<T>*& list_start, LinkedListItem<T>** list_end = nullptr) {
580 LinkedListItem<T>* list_cur = list_start; 565 LinkedListItem<T>* list_cur = list_start;
581 LinkedListItem<T>* prev = nullptr; 566 LinkedListItem<T>* prev = nullptr;
582 567
583 while (true) 568 while (true) {
584 {
585 u8 shouldExist = (list_cur ? 1 : 0); 569 u8 shouldExist = (list_cur ? 1 : 0);
586 Do(shouldExist); 570 Do(shouldExist);
587 if (shouldExist == 1) 571 if (shouldExist == 1) {
588 {
589 LinkedListItem<T>* cur = list_cur ? list_cur : TNew(); 572 LinkedListItem<T>* cur = list_cur ? list_cur : TNew();
590 TDo(*this, (T*)cur); 573 TDo(*this, (T*)cur);
591 if (!list_cur) 574 if (!list_cur) {
592 { 575 if (mode == MODE_READ) {
593 if (mode == MODE_READ)
594 {
595 cur->next = nullptr; 576 cur->next = nullptr;
596 list_cur = cur; 577 list_cur = cur;
597 if (prev) 578 if (prev)
598 prev->next = cur; 579 prev->next = cur;
599 else 580 else
600 list_start = cur; 581 list_start = cur;
601 } 582 } else {
602 else
603 {
604 TFree(cur); 583 TFree(cur);
605 continue; 584 continue;
606 } 585 }
607 } 586 }
608 } 587 } else {
609 else 588 if (mode == MODE_READ) {
610 {
611 if (mode == MODE_READ)
612 {
613 if (prev) 589 if (prev)
614 prev->next = nullptr; 590 prev->next = nullptr;
615 if (list_end) 591 if (list_end)
616 *list_end = prev; 592 *list_end = prev;
617 if (list_cur) 593 if (list_cur) {
618 {
619 if (list_start == list_cur) 594 if (list_start == list_cur)
620 list_start = nullptr; 595 list_start = nullptr;
621 do 596 do {
622 {
623 LinkedListItem<T>* next = list_cur->next; 597 LinkedListItem<T>* next = list_cur->next;
624 TFree(list_cur); 598 TFree(list_cur);
625 list_cur = next; 599 list_cur = next;
626 } 600 } while (list_cur);
627 while (list_cur);
628 } 601 }
629 } 602 }
630 break; 603 break;
@@ -634,13 +607,13 @@ public:
634 } 607 }
635 } 608 }
636 609
637 void DoMarker(const char* prevName, u32 arbitraryNumber=0x42) 610 void DoMarker(const char* prevName, u32 arbitraryNumber = 0x42) {
638 {
639 u32 cookie = arbitraryNumber; 611 u32 cookie = arbitraryNumber;
640 Do(cookie); 612 Do(cookie);
641 if(mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) 613 if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) {
642 { 614 LOG_ERROR(Common, "After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). "
643 LOG_ERROR(Common, "After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); 615 "Aborting savestate load...",
616 prevName, cookie, cookie, arbitraryNumber, arbitraryNumber);
644 SetError(ERROR_FAILURE); 617 SetError(ERROR_FAILURE);
645 } 618 }
646 } 619 }