From d34f42c679f5618b2b4a5285260a86723e82e2ad Mon Sep 17 00:00:00 2001 From: stephena Date: Sun, 11 Aug 2002 17:48:13 +0000 Subject: [PATCH] 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 --- stella/src/emucore/Deserializer.cxx | 32 +++++++++++++++---------- stella/src/emucore/Deserializer.hxx | 6 ++--- stella/src/emucore/Serializer.cxx | 28 ++++++++++++++-------- stella/src/emucore/Serializer.hxx | 6 ++--- stella/src/emucore/m6502/src/System.cxx | 29 +++++++++++++++++++++- 5 files changed, 71 insertions(+), 30 deletions(-) diff --git a/stella/src/emucore/Deserializer.cxx b/stella/src/emucore/Deserializer.cxx index 3d2499926..503db8e88 100644 --- a/stella/src/emucore/Deserializer.cxx +++ b/stella/src/emucore/Deserializer.cxx @@ -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 @@ -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 (&l), sizeof (long)); - if(myStream.bad()) + myStream->read(reinterpret_cast (&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) diff --git a/stella/src/emucore/Deserializer.hxx b/stella/src/emucore/Deserializer.hxx index 0490bb1d0..d3f128e39 100644 --- a/stella/src/emucore/Deserializer.hxx +++ b/stella/src/emucore/Deserializer.hxx @@ -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; diff --git a/stella/src/emucore/Serializer.cxx b/stella/src/emucore/Serializer.cxx index 145928356..d83ddca3f 100644 --- a/stella/src/emucore/Serializer.cxx +++ b/stella/src/emucore/Serializer.cxx @@ -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 @@ -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 (&value), sizeof (long)); - if(myStream.bad()) + myStream->write(reinterpret_cast (&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"; } diff --git a/stella/src/emucore/Serializer.hxx b/stella/src/emucore/Serializer.hxx index b63408e71..c7162d394 100644 --- a/stella/src/emucore/Serializer.hxx +++ b/stella/src/emucore/Serializer.hxx @@ -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; diff --git a/stella/src/emucore/m6502/src/System.cxx b/stella/src/emucore/m6502/src/System.cxx index 035f03e1e..6575436fc 100644 --- a/stella/src/emucore/m6502/src/System.cxx +++ b/stella/src/emucore/m6502/src/System.cxx @@ -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 @@ -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,17 +220,26 @@ 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(); @@ -239,26 +251,41 @@ 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();