mirror of https://github.com/stella-emu/stella.git
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:
parent
a6d330fa2c
commit
d34f42c679
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// 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>
|
||||
|
@ -27,41 +27,47 @@ Deserializer::Deserializer(void)
|
|||
{
|
||||
TruePattern = 0xfab1fab2;
|
||||
FalsePattern = 0xbad1bad2;
|
||||
|
||||
myStream = (ifstream*) 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Deserializer::~Deserializer(void)
|
||||
{
|
||||
close();
|
||||
if(myStream.is_open())
|
||||
myStream.close();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Deserializer::open(string& fileName)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if(myStream.is_open())
|
||||
myStream.close();
|
||||
if(myStream)
|
||||
{
|
||||
if(myStream->is_open())
|
||||
myStream->close();
|
||||
|
||||
delete myStream;
|
||||
myStream = (ifstream*) 0;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
long Deserializer::getLong(void)
|
||||
{
|
||||
if(myStream.eof())
|
||||
if(myStream->eof())
|
||||
throw "Deserializer: end of file";
|
||||
|
||||
long l;
|
||||
myStream.read(reinterpret_cast<char *> (&l), sizeof (long));
|
||||
if(myStream.bad())
|
||||
myStream->read(reinterpret_cast<char *> (&l), sizeof (long));
|
||||
if(myStream->bad())
|
||||
throw "Deserializer: file read failed";
|
||||
|
||||
return l;
|
||||
|
@ -73,9 +79,9 @@ string Deserializer::getString(void)
|
|||
long len = getLong();
|
||||
string str;
|
||||
str.resize(len);
|
||||
myStream.read(&str[0], len);
|
||||
myStream->read(&str[0], len);
|
||||
|
||||
if(myStream.bad())
|
||||
if(myStream->bad())
|
||||
throw "Deserializer: file read failed";
|
||||
|
||||
return str;
|
||||
|
@ -87,7 +93,7 @@ bool Deserializer::getBool(void)
|
|||
bool result = false;
|
||||
|
||||
long b = getLong();
|
||||
if(myStream.bad())
|
||||
if(myStream->bad())
|
||||
throw "Deserializer: file read failed";
|
||||
|
||||
if(b == TruePattern)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// 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
|
||||
|
@ -32,7 +32,7 @@
|
|||
return.
|
||||
|
||||
@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
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ class Deserializer
|
|||
|
||||
private:
|
||||
// The stream to get the deserialized data from.
|
||||
ifstream myStream;
|
||||
ifstream* myStream;
|
||||
|
||||
// A long pattern that represents a boolean value of true.
|
||||
long TruePattern;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// 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>
|
||||
|
@ -27,6 +27,8 @@ Serializer::Serializer(void)
|
|||
{
|
||||
TruePattern = 0xfab1fab2;
|
||||
FalsePattern = 0xbad1bad2;
|
||||
|
||||
myStream = (ofstream*) 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -39,23 +41,29 @@ Serializer::~Serializer(void)
|
|||
bool Serializer::open(string& fileName)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if(myStream.is_open())
|
||||
myStream.close();
|
||||
if(myStream)
|
||||
{
|
||||
if(myStream->is_open())
|
||||
myStream->close();
|
||||
|
||||
delete myStream;
|
||||
myStream = (ofstream*) 0;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Serializer::putLong(long value)
|
||||
{
|
||||
myStream.write(reinterpret_cast<char *> (&value), sizeof (long));
|
||||
if(myStream.bad())
|
||||
myStream->write(reinterpret_cast<char *> (&value), sizeof (long));
|
||||
if(myStream->bad())
|
||||
throw "Serializer: file write failed";
|
||||
}
|
||||
|
||||
|
@ -64,9 +72,9 @@ void Serializer::putString(string& str)
|
|||
{
|
||||
int len = str.length();
|
||||
putLong(len);
|
||||
myStream.write(str.data(), len);
|
||||
myStream->write(str.data(), len);
|
||||
|
||||
if(myStream.bad())
|
||||
if(myStream->bad())
|
||||
throw "Serializer: file write failed";
|
||||
}
|
||||
|
||||
|
@ -76,6 +84,6 @@ void Serializer::putBool(bool b)
|
|||
long l = b ? TruePattern: FalsePattern;
|
||||
putLong(l);
|
||||
|
||||
if(myStream.bad ())
|
||||
if(myStream->bad ())
|
||||
throw "Serializer: file write failed";
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// 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
|
||||
|
@ -33,7 +33,7 @@
|
|||
Boolean values are written using a special pattern.
|
||||
|
||||
@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
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ class Serializer
|
|||
|
||||
private:
|
||||
// The stream to send the serialized data to.
|
||||
ofstream myStream;
|
||||
ofstream* myStream;
|
||||
|
||||
// A long pattern that represents a boolean value of true.
|
||||
long TruePattern;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// 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>
|
||||
|
@ -209,7 +209,10 @@ int System::saveState(string &fileName, string& md5sum)
|
|||
{
|
||||
// Open the file as a new Serializer
|
||||
if(!serializer->open(fileName))
|
||||
{
|
||||
serializer->close();
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Prepend the state file with the md5sum of this cartridge
|
||||
// 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
|
||||
if(!save(*serializer))
|
||||
{
|
||||
serializer->close();
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Next, save state for the CPU
|
||||
if(!myM6502->save(*serializer))
|
||||
{
|
||||
serializer->close();
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Now save the state of each device
|
||||
for(uInt32 i = 0; i < myNumberOfDevices; ++i)
|
||||
{
|
||||
if(!myDevices[i]->save(*serializer))
|
||||
{
|
||||
serializer->close();
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
serializer->close();
|
||||
return 1; // success
|
||||
|
@ -239,27 +251,42 @@ int System::loadState(string &fileName, string& md5sum)
|
|||
{
|
||||
// Open the file as a new Deserializer
|
||||
if(!deserializer->open(fileName))
|
||||
{
|
||||
deserializer->close();
|
||||
return 2;
|
||||
}
|
||||
|
||||
// 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.
|
||||
if(deserializer->getString() != md5sum)
|
||||
{
|
||||
deserializer->close();
|
||||
return 3;
|
||||
}
|
||||
|
||||
// First load state for this system
|
||||
if(!load(*deserializer))
|
||||
{
|
||||
deserializer->close();
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Next, load state for the CPU
|
||||
if(!myM6502->load(*deserializer))
|
||||
{
|
||||
deserializer->close();
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Now load the state of each device
|
||||
for(uInt32 i = 0; i < myNumberOfDevices; ++i)
|
||||
{
|
||||
if(!myDevices[i]->load(*deserializer))
|
||||
{
|
||||
deserializer->close();
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
deserializer->close();
|
||||
return 1; // success
|
||||
|
|
Loading…
Reference in New Issue