BizHawk/BizHawk.Emulation.Common/CodeDataLog.cs

138 lines
2.8 KiB
C#
Raw Normal View History

2015-11-01 21:01:19 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Common
{
public class CodeDataLog : Dictionary<string, byte[]>
{
public CodeDataLog()
{
}
/// <summary>
/// This is just a hook, if needed, to readily suspend logging, without having to rewire the core
/// </summary>
public bool Active = true;
public string SubType;
public int SubVer;
/// <summary>
/// Tests whether the other CodeDataLog is structurally identical
/// </summary>
public bool Check(CodeDataLog other)
{
if (SubType != other.SubType)
return false;
if (SubVer != other.SubVer)
return false;
if (this.Count != other.Count)
return false;
foreach (var kvp in this)
{
if (!other.ContainsKey(kvp.Key))
return false;
var oval = other[kvp.Key];
if (oval.Length != kvp.Value.Length)
return false;
}
return true;
}
public void LogicalOrFrom(CodeDataLog other)
{
if (this.Count != other.Count)
throw new InvalidDataException("Dictionaries must have the same number of keys!");
foreach (var kvp in other)
{
byte[] fromdata = kvp.Value;
byte[] todata = this[kvp.Key];
if (fromdata.Length != todata.Length)
throw new InvalidDataException("Memory regions must be the same size!");
for (int i = 0; i < todata.Length; i++)
todata[i] |= fromdata[i];
}
}
public void ClearData()
{
foreach (byte[] data in Values)
Array.Clear(data, 0, data.Length);
}
public void Save(Stream s)
{
_Save(s, true);
}
Dictionary<string, long> _Save(Stream s, bool forReal)
{
var ret = new Dictionary<string, long>();
var w = new BinaryWriter(s);
w.Write("BIZHAWK-CDL-2");
w.Write(SubType.PadRight(15));
w.Write(Count);
w.Flush();
long addr = s.Position;
if (forReal)
{
foreach (var kvp in this)
{
w.Write(kvp.Key);
w.Write(kvp.Value.Length);
w.Write(kvp.Value);
}
}
else
{
foreach (var kvp in this)
{
addr += kvp.Key.Length + 1; //assumes shortly-encoded key names
addr += 4;
ret[kvp.Key] = addr;
addr += kvp.Value.Length;
}
}
w.Flush();
return ret;
}
public Dictionary<string, long> GetBlockMap()
{
return _Save(new MemoryStream(), false);
}
public void Load(Stream s)
{
var br = new BinaryReader(s);
string id = br.ReadString();
if (id == "BIZHAWK-CDL-1")
SubType = "PCE";
else if (id == "BIZHAWK-CDL-2")
SubType = br.ReadString().TrimEnd(' ');
else
throw new InvalidDataException("File is not a Bizhawk CDL file!");
int count = br.ReadInt32();
for (int i = 0; i < count; i++)
{
string key = br.ReadString();
int len = br.ReadInt32();
byte[] data = br.ReadBytes(len);
this[key] = data;
}
}
}
}