using System; using ICSharpCode.SharpZipLib.Zip; using System.IO; namespace BizHawk.Client.Common { public class BinaryStateFileNames { public const string Versiontag = "BizState 1.0"; public const string Corestate = "Core"; public const string Framebuffer = "Framebuffer"; public const string Input = "Input Log"; } public class BinaryStateLoader : IDisposable { private bool isDisposed; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!isDisposed) { isDisposed = true; if (disposing) { zip.Close(); } } } ZipFile zip; private BinaryStateLoader() { } public static BinaryStateLoader LoadAndDetect(string Filename) { BinaryStateLoader ret = new BinaryStateLoader(); try { ret.zip = new ZipFile(Filename); var e = ret.zip.GetEntry(BinaryStateFileNames.Versiontag); if (e == null) { ret.zip.Close(); return null; } return ret; } catch (ZipException) { return null; } } bool GetFileByName(string Name, bool abort, Action callback) { var e = zip.GetEntry(Name); if (e != null) { using (Stream zs = zip.GetInputStream(e)) { callback(zs); } return true; } else if (abort) { throw new Exception("Essential zip section not found: " + Name); } else { return false; } } public void GetCoreState(Action callback) { GetFileByName(BinaryStateFileNames.Corestate, true, callback); } public bool GetFrameBuffer(Action callback) { return GetFileByName(BinaryStateFileNames.Framebuffer, false, callback); } public void GetInputLogRequired(Action callback) { GetFileByName(BinaryStateFileNames.Input, true, callback); } } public class BinaryStateSaver : IDisposable { private readonly ZipOutputStream zip; /// /// /// /// not closed when finished! public BinaryStateSaver(Stream s) { zip = new ZipOutputStream(s) { IsStreamOwner = false, UseZip64 = UseZip64.Off }; zip.SetLevel(0); PutFileByName(BinaryStateFileNames.Versiontag, ss => { }); } void PutFileByName(string Name, Action callback) { var e = new ZipEntry(Name) {CompressionMethod = CompressionMethod.Stored}; zip.PutNextEntry(e); callback(zip); zip.CloseEntry(); } public void PutCoreState(Action callback) { PutFileByName(BinaryStateFileNames.Corestate, callback); } public void PutFrameBuffer(Action callback) { PutFileByName(BinaryStateFileNames.Framebuffer, callback); } public void PutInputLog(Action callback) { PutFileByName(BinaryStateFileNames.Input, callback); } private bool isDisposed; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!isDisposed) { isDisposed = true; if (disposing) { zip.Close(); } } } } }