blob: aadf0cc2514908c9ed9473fa14abd4e17c0c9e8a [file] [log] [blame] [raw]
#include <cstring>
#include "SaveState.h"
const char SSSTRING[] = "YSS0";
FILE *SaveState::ssfp = NULL;
template<> unsigned int LinkedList<SaveState>::count = 0;
template<> SaveState* LinkedList<SaveState>::root = 0;
template<> SaveState* LinkedList<SaveState>::last = 0;
SaveState::SaveState()
{
add(this);
}
SaveState::~SaveState()
{
remove(this);
}
void SaveState::setId(const char *id)
{
strcpy(componentName, id);
}
SaveState *SaveState::findId(const char *id)
{
SaveState *ss = SaveState::getRoot();
while (ss) {
if (!strncmp(ss->getId(), id, 4))
return ss;
ss = ss->getNext();
}
return NULL;
}
bool SaveState::openSnapshot(char *fname, bool isWrite)
{
const char *mode = isWrite ? "wb" : "rb";
ssfp = fopen(fname, mode);
if (!ssfp)
return false;
if (isWrite) {
SaveState *ss = SaveState::getRoot();
fwrite(SSSTRING, 4, 1, ssfp);
while (ss) {
fwrite(ss->getId(), 4, 1, ssfp);
ss->dumpState();
ss = ss->getNext();
}
} else {
char hdr[5];
fread(hdr, 4, 1, ssfp);
// check header signature
if (strncmp(SSSTRING, hdr, 4)) {
closeSnapshot();
return false;
}
do {
char id[8];
// read chunk header & find it
// keep reading if not found (should be 4-byte aligned)
fread(id, 4, 1, ssfp);
SaveState *ss = findId(id);
if (ss) {
fprintf(stderr, "Snapshot chunk %.*s found.\n", 4, id);
ss->readState();
}
} while (!feof(ssfp));
}
closeSnapshot();
return true;
}
void SaveState::closeSnapshot()
{
fclose(ssfp);
}
void SaveState::saveVar(void *p, size_t size)
{
if (ssfp) {
size_t w = fwrite(p, 1, size, ssfp);
// padding to 4-byte boundary so that chunk ID's always found
w = ((w + 3) & ~3);
// dummy output
while (size++ < w) {
fputc('\0', ssfp);
}
}
}
size_t SaveState::readVar(void *p, size_t size)
{
if (ssfp) {
size_t r = fread(p, 1, size, ssfp);
// padding to 4-byte boundary so that chunk ID's always found
r = ((r + 3) & ~3);
// dummy input
while (size++ < r) {
unsigned char in = fgetc(ssfp);
}
return size;
}
return 0;
}