Fixed state loading and saving. When a load failed on a previous attempt,

the next load would cause the program to abort.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@106 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2002-08-11 17:48:13 +00:00
parent a6d330fa2c
commit d34f42c679
5 changed files with 71 additions and 30 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Deserializer.cxx,v 1.1 2002-05-13 19:14:17 stephena Exp $ // $Id: Deserializer.cxx,v 1.2 2002-08-11 17:48:13 stephena Exp $
//============================================================================ //============================================================================
#include <iostream> #include <iostream>
@ -27,41 +27,47 @@ Deserializer::Deserializer(void)
{ {
TruePattern = 0xfab1fab2; TruePattern = 0xfab1fab2;
FalsePattern = 0xbad1bad2; FalsePattern = 0xbad1bad2;
myStream = (ifstream*) 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Deserializer::~Deserializer(void) Deserializer::~Deserializer(void)
{ {
close(); close();
if(myStream.is_open())
myStream.close();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Deserializer::open(string& fileName) bool Deserializer::open(string& fileName)
{ {
close(); close();
myStream.open(fileName.c_str(), ios::in | ios::binary); myStream = new ifstream(fileName.c_str(), ios::in | ios::binary);
return myStream.is_open(); return (myStream && myStream->is_open());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Deserializer::close(void) void Deserializer::close(void)
{ {
if(myStream.is_open()) if(myStream)
myStream.close(); {
if(myStream->is_open())
myStream->close();
delete myStream;
myStream = (ifstream*) 0;
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
long Deserializer::getLong(void) long Deserializer::getLong(void)
{ {
if(myStream.eof()) if(myStream->eof())
throw "Deserializer: end of file"; throw "Deserializer: end of file";
long l; long l;
myStream.read(reinterpret_cast<char *> (&l), sizeof (long)); myStream->read(reinterpret_cast<char *> (&l), sizeof (long));
if(myStream.bad()) if(myStream->bad())
throw "Deserializer: file read failed"; throw "Deserializer: file read failed";
return l; return l;
@ -73,9 +79,9 @@ string Deserializer::getString(void)
long len = getLong(); long len = getLong();
string str; string str;
str.resize(len); str.resize(len);
myStream.read(&str[0], len); myStream->read(&str[0], len);
if(myStream.bad()) if(myStream->bad())
throw "Deserializer: file read failed"; throw "Deserializer: file read failed";
return str; return str;
@ -87,7 +93,7 @@ bool Deserializer::getBool(void)
bool result = false; bool result = false;
long b = getLong(); long b = getLong();
if(myStream.bad()) if(myStream->bad())
throw "Deserializer: file read failed"; throw "Deserializer: file read failed";
if(b == TruePattern) if(b == TruePattern)

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Deserializer.hxx,v 1.3 2002-05-14 15:22:28 stephena Exp $ // $Id: Deserializer.hxx,v 1.4 2002-08-11 17:48:13 stephena Exp $
//============================================================================ //============================================================================
#ifndef DESERIALIZER_HXX #ifndef DESERIALIZER_HXX
@ -32,7 +32,7 @@
return. return.
@author Stephen Anthony @author Stephen Anthony
@version $Id: Deserializer.hxx,v 1.3 2002-05-14 15:22:28 stephena Exp $ @version $Id: Deserializer.hxx,v 1.4 2002-08-11 17:48:13 stephena Exp $
*/ */
class Deserializer class Deserializer
{ {
@ -88,7 +88,7 @@ class Deserializer
private: private:
// The stream to get the deserialized data from. // The stream to get the deserialized data from.
ifstream myStream; ifstream* myStream;
// A long pattern that represents a boolean value of true. // A long pattern that represents a boolean value of true.
long TruePattern; long TruePattern;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Serializer.cxx,v 1.1 2002-05-13 19:14:17 stephena Exp $ // $Id: Serializer.cxx,v 1.2 2002-08-11 17:48:13 stephena Exp $
//============================================================================ //============================================================================
#include <iostream> #include <iostream>
@ -27,6 +27,8 @@ Serializer::Serializer(void)
{ {
TruePattern = 0xfab1fab2; TruePattern = 0xfab1fab2;
FalsePattern = 0xbad1bad2; FalsePattern = 0xbad1bad2;
myStream = (ofstream*) 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -39,23 +41,29 @@ Serializer::~Serializer(void)
bool Serializer::open(string& fileName) bool Serializer::open(string& fileName)
{ {
close(); close();
myStream.open(fileName.c_str(), ios::out | ios::binary); myStream = new ofstream(fileName.c_str(), ios::out | ios::binary);
return myStream.is_open(); return (myStream && myStream->is_open());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Serializer::close(void) void Serializer::close(void)
{ {
if(myStream.is_open()) if(myStream)
myStream.close(); {
if(myStream->is_open())
myStream->close();
delete myStream;
myStream = (ofstream*) 0;
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Serializer::putLong(long value) void Serializer::putLong(long value)
{ {
myStream.write(reinterpret_cast<char *> (&value), sizeof (long)); myStream->write(reinterpret_cast<char *> (&value), sizeof (long));
if(myStream.bad()) if(myStream->bad())
throw "Serializer: file write failed"; throw "Serializer: file write failed";
} }
@ -64,9 +72,9 @@ void Serializer::putString(string& str)
{ {
int len = str.length(); int len = str.length();
putLong(len); putLong(len);
myStream.write(str.data(), len); myStream->write(str.data(), len);
if(myStream.bad()) if(myStream->bad())
throw "Serializer: file write failed"; throw "Serializer: file write failed";
} }
@ -76,6 +84,6 @@ void Serializer::putBool(bool b)
long l = b ? TruePattern: FalsePattern; long l = b ? TruePattern: FalsePattern;
putLong(l); putLong(l);
if(myStream.bad ()) if(myStream->bad ())
throw "Serializer: file write failed"; throw "Serializer: file write failed";
} }

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Serializer.hxx,v 1.3 2002-05-14 15:22:28 stephena Exp $ // $Id: Serializer.hxx,v 1.4 2002-08-11 17:48:13 stephena Exp $
//============================================================================ //============================================================================
#ifndef SERIALIZER_HXX #ifndef SERIALIZER_HXX
@ -33,7 +33,7 @@
Boolean values are written using a special pattern. Boolean values are written using a special pattern.
@author Stephen Anthony @author Stephen Anthony
@version $Id: Serializer.hxx,v 1.3 2002-05-14 15:22:28 stephena Exp $ @version $Id: Serializer.hxx,v 1.4 2002-08-11 17:48:13 stephena Exp $
*/ */
class Serializer class Serializer
{ {
@ -89,7 +89,7 @@ class Serializer
private: private:
// The stream to send the serialized data to. // The stream to send the serialized data to.
ofstream myStream; ofstream* myStream;
// A long pattern that represents a boolean value of true. // A long pattern that represents a boolean value of true.
long TruePattern; long TruePattern;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: System.cxx,v 1.3 2002-05-13 19:10:25 stephena Exp $ // $Id: System.cxx,v 1.4 2002-08-11 17:48:13 stephena Exp $
//============================================================================ //============================================================================
#include <assert.h> #include <assert.h>
@ -209,7 +209,10 @@ int System::saveState(string &fileName, string& md5sum)
{ {
// Open the file as a new Serializer // Open the file as a new Serializer
if(!serializer->open(fileName)) if(!serializer->open(fileName))
{
serializer->close();
return 2; return 2;
}
// Prepend the state file with the md5sum of this cartridge // Prepend the state file with the md5sum of this cartridge
// This is the first defensive check for an invalid state file // This is the first defensive check for an invalid state file
@ -217,18 +220,27 @@ int System::saveState(string &fileName, string& md5sum)
// First save state for this system // First save state for this system
if(!save(*serializer)) if(!save(*serializer))
{
serializer->close();
return 3; return 3;
}
// Next, save state for the CPU // Next, save state for the CPU
if(!myM6502->save(*serializer)) if(!myM6502->save(*serializer))
{
serializer->close();
return 3; return 3;
}
// Now save the state of each device // Now save the state of each device
for(uInt32 i = 0; i < myNumberOfDevices; ++i) for(uInt32 i = 0; i < myNumberOfDevices; ++i)
{ {
if(!myDevices[i]->save(*serializer)) if(!myDevices[i]->save(*serializer))
{
serializer->close();
return 3; return 3;
} }
}
serializer->close(); serializer->close();
return 1; // success return 1; // success
@ -239,27 +251,42 @@ int System::loadState(string &fileName, string& md5sum)
{ {
// Open the file as a new Deserializer // Open the file as a new Deserializer
if(!deserializer->open(fileName)) if(!deserializer->open(fileName))
{
deserializer->close();
return 2; return 2;
}
// Look at the beginning of the state file. It should contain the md5sum // Look at the beginning of the state file. It should contain the md5sum
// of the current cartridge. If it doesn't, this state file is invalid. // of the current cartridge. If it doesn't, this state file is invalid.
if(deserializer->getString() != md5sum) if(deserializer->getString() != md5sum)
{
deserializer->close();
return 3; return 3;
}
// First load state for this system // First load state for this system
if(!load(*deserializer)) if(!load(*deserializer))
{
deserializer->close();
return 3; return 3;
}
// Next, load state for the CPU // Next, load state for the CPU
if(!myM6502->load(*deserializer)) if(!myM6502->load(*deserializer))
{
deserializer->close();
return 3; return 3;
}
// Now load the state of each device // Now load the state of each device
for(uInt32 i = 0; i < myNumberOfDevices; ++i) for(uInt32 i = 0; i < myNumberOfDevices; ++i)
{ {
if(!myDevices[i]->load(*deserializer)) if(!myDevices[i]->load(*deserializer))
{
deserializer->close();
return 3; return 3;
} }
}
deserializer->close(); deserializer->close();
return 1; // success return 1; // success