using Be.Windows.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mesen.GUI.Debugger
{
///
/// The default implementation.
///
class TblByteCharConverter : IByteCharConverter
{
Dictionary _tblRules;
Dictionary _reverseTblRules;
List _stringList;
bool[] _hasPotentialRule = new bool[256];
public TblByteCharConverter(Dictionary tblRules)
{
this._tblRules = tblRules;
foreach(KeyValuePair kvp in tblRules) {
_hasPotentialRule[kvp.Key.Key & 0xFF] = true;
}
this._stringList = new List();
this._reverseTblRules = new Dictionary();
foreach(KeyValuePair kvp in tblRules) {
this._stringList.Add(kvp.Value);
this._reverseTblRules[kvp.Value] = kvp.Key;
}
this._stringList.Sort(new Comparison((a, b) => {
if(a.Length > b.Length) {
return 1;
} else if(a.Length < b.Length) {
return -1;
} else {
return string.Compare(a, b);
}
}));
}
///
/// Returns the character to display for the byte passed across.
///
///
///
public virtual string ToChar(UInt64 value, out int keyLength)
{
if(!_hasPotentialRule[value & 0xFF]) {
keyLength = 1;
return ".";
}
int byteCount = 8;
string result;
while(!_tblRules.TryGetValue(new TblKey() { Key = value, Length = byteCount }, out result) && byteCount > 0) {
value &= ~(((UInt64)0xFF) << (8 * (byteCount - 1)));
byteCount--;
}
if(result != null) {
keyLength = byteCount;
return result;
} else {
keyLength = 1;
return ".";
}
}
public virtual byte[] GetBytes(string text)
{
List bytes = new List();
bool match = false;
while(text.Length > 0) {
do {
match = false;
foreach(string key in _stringList) {
//Without an ordinal comparison, it's possible for an empty string to "StartsWith" a non-empty string (e.g replacement char U+FFFD)
//This causes a crash here (because key.Length > text.Length)
if(text.StartsWith(key, StringComparison.Ordinal)) {
bytes.AddRange(_reverseTblRules[key].GetBytes());
text = text.Substring(key.Length);
match = true;
break;
}
}
} while(match);
if(!match && text.Length > 0) {
bytes.Add(0);
text = text.Substring(1);
}
}
return bytes.ToArray();
}
///
/// Returns the byte to use for the character passed across.
///
///
///
public virtual byte ToByte(char c)
{
return (byte)c;
}
///
/// Returns a description of the byte char provider.
///
///
public override string ToString()
{
return "TBL";
}
}
}