- refactor ViewPort constructor to not need to take in the data array twice

- when searching for text, check if the found results are anchors
- when adding a text anchor with no name, search for pointers before rejecting it
This commit is contained in:
Benjamin Popp 2019-02-09 12:29:47 -06:00
parent b05d7d0a5f
commit bb00a22fc5
16 changed files with 197 additions and 121 deletions

View File

@ -30,6 +30,7 @@ namespace HavenSoft.HexManiac.Core.Models {
void Load(byte[] newData, StoredMetadata metadata);
void ExpandData(ModelDelta changeToken, int minimumLength);
IReadOnlyList<int> SearchForPointersToAnchor(ModelDelta changeToken, int address);
void WritePointer(ModelDelta changeToken, int address, int pointerDestination);
void WriteValue(ModelDelta changeToken, int address, int value);
int ReadPointer(int address);
@ -86,6 +87,8 @@ namespace HavenSoft.HexManiac.Core.Models {
public abstract IFormattedRun RelocateForExpansion(ModelDelta changeToken, IFormattedRun run, int minimumLength);
public abstract IReadOnlyList<int> SearchForPointersToAnchor(ModelDelta changeToken, int address);
public int ReadValue(int index) {
int word = 0;
word |= RawData[index + 0] << 0;
@ -130,6 +133,8 @@ namespace HavenSoft.HexManiac.Core.Models {
for (int i = 0; i < length; i++) changeToken.ChangeData(this, start + i, 0xFF);
}
public override IReadOnlyList<int> SearchForPointersToAnchor(ModelDelta changeToken, int address) => throw new NotImplementedException();
public override string Copy(int start, int length) {
var bytes = Enumerable.Range(start, length).Select(i => RawData[i]);
return string.Join(" ", bytes.Select(value => value.ToString("X2")));

View File

@ -609,6 +609,27 @@ namespace HavenSoft.HexManiac.Core.Models {
return new StoredMetadata(anchors, unmappedPointers);
}
public override IReadOnlyList<int> SearchForPointersToAnchor(ModelDelta changeToken, int address) {
var results = new List<int>();
for (int i = 3; i < RawData.Length; i++) {
if (RawData[i] != 0x08 && RawData[i] != 0x09) continue;
int destination = ReadPointer(i - 3);
if (destination != address) continue;
var index = BinarySearch(i - 3);
if (index >= 0) continue;
index = ~index;
if (index < runs.Count && runs[index].Start <= i) continue;
if (index > 0 && runs[index - 1].Start + runs[index - 1].Length > i - 3) continue;
var newRun = new PointerRun(i - 3);
runs.Insert(index, newRun);
changeToken.AddRun(newRun);
results.Add(i - 3);
}
return results;
}
private static (string, string) SplitNameAndFormat(string text) {
var name = text.Substring(1).Trim();
string format = string.Empty;
@ -724,27 +745,6 @@ namespace HavenSoft.HexManiac.Core.Models {
return sources;
}
private IReadOnlyList<int> SearchForPointersToAnchor(ModelDelta changeToken, int address) {
var results = new List<int>();
for (int i = 3; i < RawData.Length; i++) {
if (RawData[i] != 0x08 && RawData[i] != 0x09) continue;
int destination = ReadPointer(i - 3);
if (destination != address) continue;
var index = BinarySearch(i-3);
if (index >= 0) continue;
index = ~index;
if (index < runs.Count && runs[index].Start <= i) continue;
if (index > 0 && runs[index - 1].Start + runs[index - 1].Length > i - 3) continue;
var newRun = new PointerRun(i - 3);
runs.Insert(index, newRun);
changeToken.AddRun(newRun);
results.Add(i - 3);
}
return results;
}
private IFormattedRun MoveRun(ModelDelta changeToken, IFormattedRun run, int newStart) {
// repoint
foreach (var source in run.PointerSources) {

View File

@ -7,7 +7,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
public class ChildViewPort : ViewPort, IChildViewPort {
public IViewPort Parent { get; }
public ChildViewPort(IViewPort viewPort) : base(new Models.LoadedFile(string.Empty, viewPort.Model.RawData), viewPort.Model) {
public ChildViewPort(IViewPort viewPort) : base(string.Empty, viewPort.Model) {
Parent = viewPort;
Width = Parent.Width;
}

View File

@ -218,7 +218,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
var file = arg as LoadedFile ?? fileSystem.OpenFile("GameBoy Advanced", "gba");
if (file == null) return;
var metadata = fileSystem.MetadataFor(file.Name);
Add(new ViewPort(file, new AutoSearchModel(file.Contents, metadata)));
Add(new ViewPort(file.Name, new AutoSearchModel(file.Contents, metadata)));
};
ImplementFindCommands();

View File

@ -283,12 +283,12 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
public ViewPort() : this(new LoadedFile(string.Empty, new byte[0])) { }
public ViewPort(LoadedFile file, IDataModel model = null) {
public ViewPort(string fileName, IDataModel model) {
history = new ChangeHistory<ModelDelta>(RevertChanges);
history.PropertyChanged += HistoryPropertyChanged;
Model = model ?? new BasicModel(file.Contents);
FileName = file.Name;
Model = model;
FileName = fileName;
scroll = new ScrollRegion { DataLength = Model.Count };
scroll.PropertyChanged += ScrollPropertyChanged;
@ -306,6 +306,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
RefreshBackingData();
}
public ViewPort(LoadedFile file) : this(file.Name, new BasicModel(file.Contents)) { }
private void ImplementCommands() {
clear.CanExecute = CanAlwaysExecute;
clear.Execute = arg => {
@ -440,7 +442,9 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
var pcsBytes = PCSString.Convert(cleanedSearchString);
pcsBytes.RemoveAt(pcsBytes.Count - 1); // remove the 0xFF that was added, since we're searching for a string segment instead of a whole string.
searchBytes.AddRange(pcsBytes.Select(b => new PCSSearchByte(b)));
results.AddRange(Search(searchBytes));
var textResults = Search(searchBytes).ToList();
ConsiderResultsAsTextRuns(textResults);
results.AddRange(textResults);
}
// it might be a pointer without angle braces
@ -469,6 +473,25 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
return results;
}
// for each of the results, we recognized it as text: see if we need to add a matching string run / pointers
private int ConsiderResultsAsTextRuns(IEnumerable<int> searchResults) {
int resultsRecognizedAsTextRuns = 0;
foreach (var result in searchResults) {
var nextRun = Model.GetNextRun(result);
if (nextRun.Start <= result) continue;
var pointers = Model.SearchForPointersToAnchor(history.CurrentChange, result);
if (pointers.Count == 0) continue;
var newRun = new PCSRun(result, PCSString.ReadString(Model, result, true), pointers);
if (newRun.Length < 1) continue;
if (newRun.Start + newRun.Length > nextRun.Start) continue;
Model.ObserveAnchorWritten(history.CurrentChange, string.Empty, newRun);
resultsRecognizedAsTextRuns++;
}
return resultsRecognizedAsTextRuns;
}
private byte[] Parse(string content) {
var result = new byte[content.Length / 2];
for (int i = 0; i < result.Length; i++) {
@ -919,13 +942,26 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
private bool CompleteAnchorEdit(Point point) {
var underEdit = (UnderEdit)currentView[point.X, point.Y].Format;
var index = scroll.ViewPointToDataIndex(point);
var errorInfo = PokemonModel.ApplyAnchor(Model, history.CurrentChange, index, underEdit.CurrentText);
ErrorInfo errorInfo;
// if it's an unnamed text anchor, we have special logic for that
if (underEdit.CurrentText == "^\"\" ") {
int count = ConsiderResultsAsTextRuns(new[] { index });
if (count == 0) {
errorInfo = new ErrorInfo("An anchor with nothing pointing to it must have a name.");
} else {
errorInfo = ErrorInfo.NoError;
}
} else {
errorInfo = PokemonModel.ApplyAnchor(Model, history.CurrentChange, index, underEdit.CurrentText);
}
ClearEdits(point);
UpdateToolsFromSelection(index);
if (errorInfo == ErrorInfo.NoError) return true;
OnError(this, errorInfo.ErrorMessage);
OnError?.Invoke(this, errorInfo.ErrorMessage);
return false;
}

View File

@ -56,7 +56,7 @@ namespace HavenSoft.HexManiac.Tests {
var model = new PokemonModel(buffer);
ArrayRun.TryParse(model, "[name\"\"12]13", 12, null, out var arrayRun);
model.ObserveRunWritten(new ModelDelta(), arrayRun);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { PreferredWidth = -1, Width = 12, Height = 20 };
var viewPort = new ViewPort("file.txt", model) { PreferredWidth = -1, Width = 12, Height = 20 };
// spot checks: it should look like a string that starts where the segment starts
var pcs = (PCS)viewPort[0, 4].Format;
@ -87,7 +87,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanParseArrayAnchorAddedFromViewPort() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob[name\"\"14]12 ");
@ -98,7 +98,7 @@ namespace HavenSoft.HexManiac.Tests {
public void ChangingAnchorTextWhileAnchorStartIsOutOfViewWorks() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob[name\"\"16]16 ");
viewPort.ScrollValue = 2;
@ -113,7 +113,7 @@ namespace HavenSoft.HexManiac.Tests {
WriteStrings(buffer, 0x00, "bob", "tom", "sam", "car", "pal", "egg");
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^words[word\"\"4] "); // notice, no length is given
@ -127,7 +127,7 @@ namespace HavenSoft.HexManiac.Tests {
WriteStrings(buffer, 100, "bobb", "tomm", "samm", "carr", "pall", "eggg");
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^words[word\"\"5] "); // notice, no length is given
@ -156,7 +156,7 @@ namespace HavenSoft.HexManiac.Tests {
var model = new PokemonModel(buffer);
ArrayRun.TryParse(model, "[word\"\"5]", 0, null, out var arrayRun);
model.ObserveAnchorWritten(new ModelDelta(), "words", arrayRun);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(6, 0);
viewPort.Edit("a"); // change "tomm" to "tamm"
@ -168,7 +168,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanPasteArray() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^strings[name\"\"16] ");
viewPort.Edit("+\"bob\" +\"sam\" +\"steve\" +\"kevin\"");
@ -181,7 +181,7 @@ namespace HavenSoft.HexManiac.Tests {
public void PastingArrayLeavesArrayFormat() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^pokenames[name\"\"11] +\"??????????\"+\"BULBASAUR\"");
viewPort.SelectionStart = new Point(0, 0);
@ -203,7 +203,7 @@ namespace HavenSoft.HexManiac.Tests {
ArrayRun.TryParse(model, "[word\"\"5]", 100, null, out var arrayRun);
model.ObserveAnchorWritten(new ModelDelta(), "words", arrayRun);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.FollowLink(0, 7); // 7*16 = 112, right in the middle of our data
// note that this will change our width to 15, because we're linking to data of width 5 when our maxwidth is 16.
@ -229,7 +229,7 @@ namespace HavenSoft.HexManiac.Tests {
ArrayRun.TryParse(model, "[word\"\"5]", 100, null, out var arrayRun);
model.ObserveAnchorWritten(new ModelDelta(), "words", arrayRun);
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.FollowLink(0, 7); // 7*16 = 112, right in the middle of our data
@ -255,7 +255,7 @@ namespace HavenSoft.HexManiac.Tests {
var model = new PokemonModel(buffer);
model.WritePointer(delta, 0x00, 0x20);
model.ObserveRunWritten(delta, new PointerRun(0x00));
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 2);
viewPort.Edit("^testdata[name\"\"16]5 ");
@ -304,7 +304,7 @@ namespace HavenSoft.HexManiac.Tests {
model.ObserveRunWritten(delta, new PointerRun(0x00));
model.WritePointer(delta, 0x04, 0x90);
model.ObserveRunWritten(delta, new PointerRun(0x04)); // the anchor at 0x90 should prevent a paste overwrite
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 2);
viewPort.Edit("^testdata[name\"\"16]5 ");
viewPort.OnError += (sender, message) => errors.Add(message);
@ -342,7 +342,7 @@ namespace HavenSoft.HexManiac.Tests {
model.ObserveRunWritten(delta, new PointerRun(0x00));
model.WritePointer(delta, 0x04, 0x90);
model.ObserveRunWritten(delta, new PointerRun(0x04)); // the anchor at 0x90 should prevent a paste overwrite
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 2);
viewPort.Edit("^testdata[name\"\"16]5 ");
viewPort.OnError += (sender, message) => errors.Add(message);
@ -381,7 +381,7 @@ namespace HavenSoft.HexManiac.Tests {
model.ObserveRunWritten(delta, new PointerRun(0x00));
model.WritePointer(delta, 0x04, 0x90);
model.ObserveRunWritten(delta, new PointerRun(0x04)); // the anchor at 0x90 should prevent a paste overwrite
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 2);
viewPort.Edit("^testdata[name\"\"16]5 ");
viewPort.OnError += (sender, message) => errors.Add(message);
@ -400,7 +400,7 @@ namespace HavenSoft.HexManiac.Tests {
public void ArarysSupportIntegers() {
var buffer = new byte[0x200];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
var errors = new List<string>();
viewPort.OnError += (sender, e) => errors.Add(e);
@ -414,7 +414,7 @@ namespace HavenSoft.HexManiac.Tests {
public void ArrayExtendsIfBasedOnAnotherNameWhichIsExtended() {
var buffer = new byte[0x200];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
var errors = new List<string>();
viewPort.OnError += (sender, e) => errors.Add(e);
@ -438,7 +438,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanEditIntsInArray() {
var buffer = new byte[0x200];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
var errors = new List<string>();
viewPort.OnError += (sender, e) => errors.Add(e);
viewPort.Edit("^sample[code:]8 ");

View File

@ -15,7 +15,7 @@ namespace HavenSoft.HexManiac.Tests {
model[0x12] = (byte)'c';
model[0x13] = (byte)'d';
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 1);
viewPort.Edit("^data`asc`4 ");
@ -34,7 +34,7 @@ namespace HavenSoft.HexManiac.Tests {
model.ObserveRunWritten(new ModelDelta(), new AsciiRun(0x10, 4));
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(1, 1);
viewPort.Edit("3");

View File

@ -195,7 +195,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanUndoFormatChange() {
var data = new byte[0x100];
var model = new PokemonModel(data);
var viewPort = new ViewPort(new LoadedFile("test.txt", data), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(4, 0);
viewPort.Edit("<000030>");
@ -209,7 +209,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanUndoDataMove() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(8, 0);
viewPort.Edit("<000030>");
@ -229,7 +229,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanUndoFromToolChange() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" ");
@ -249,7 +249,7 @@ namespace HavenSoft.HexManiac.Tests {
public void UndoCanHandleNameMove() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
// operation 1
viewPort.Edit("<bob> 03 08 24 16 <bob>");
@ -280,7 +280,7 @@ namespace HavenSoft.HexManiac.Tests {
public void UndoWorksAfterMidPointerEdit() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("<000100>");
viewPort.SelectionStart = new Point(1, 0);
@ -294,7 +294,7 @@ namespace HavenSoft.HexManiac.Tests {
public void UndoRedoRestoresUnmappedNames() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("<bob>");
viewPort.SelectionStart = new Point(0, 0);

View File

@ -198,7 +198,7 @@ namespace HavenSoft.HexManiac.Tests {
public void SearchFor6BytesAlsoFindsPointers() {
var data = new byte[0x1200];
var model = new PokemonModel(data);
var viewPort = new ViewPort(new LoadedFile("file.txt", data), model);
var viewPort = new ViewPort("file.txt", model);
viewPort.Edit("<001060>");
var results = viewPort.Find("001060");

View File

@ -78,7 +78,7 @@ namespace HavenSoft.HexManiac.Tests {
public void ModelUpdatesWhenViewPortChanges() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model);
var viewPort = new ViewPort("file.txt", model);
viewPort.Edit("<000020>");
@ -90,7 +90,7 @@ namespace HavenSoft.HexManiac.Tests {
public void WritingNamedAnchorFollowedByPointerToNameWorks() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model);
var viewPort = new ViewPort("file.txt", model);
viewPort.SelectionStart = new Point(0, 1);
viewPort.Edit("^bob ");
@ -104,7 +104,7 @@ namespace HavenSoft.HexManiac.Tests {
public void WritingPointerToNameFollowedByNamedAnchorWorks() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model);
var viewPort = new ViewPort("file.txt", model);
viewPort.SelectionStart = new Point(0, 2);
viewPort.Edit("<bob>");
@ -118,7 +118,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanWriteAnchorToSameLocationAsPointerWithoutRemovingPointer() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model);
var viewPort = new ViewPort("file.txt", model);
viewPort.SelectionStart = new Point(0, 2);
viewPort.Edit("<000040>");
@ -132,7 +132,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanWriteAnchorToSameLocationAsPointerPointingToThatAnchor() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model);
var viewPort = new ViewPort("file.txt", model);
viewPort.SelectionStart = new Point(0, 2);
viewPort.Edit("<bob>");
@ -147,7 +147,7 @@ namespace HavenSoft.HexManiac.Tests {
public void WritingAnAnchorUpdatesPointersToUseThatName() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model);
var viewPort = new ViewPort("file.txt", model);
viewPort.SelectionStart = new Point(0, 2);
viewPort.Edit("<000004>");
@ -215,7 +215,7 @@ namespace HavenSoft.HexManiac.Tests {
public void PointerCanPointToNameAfterThatNameGetsDeleted() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 16, Height = 16 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
var token = new ModelDelta();
viewPort.SelectionStart = new Point(0, 1);
@ -237,7 +237,7 @@ namespace HavenSoft.HexManiac.Tests {
public void PointerGetsSetToZeroAfterAnchorGetsDeleted() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 16, Height = 16 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
var token = new ModelDelta();
viewPort.SelectionStart = new Point(0, 1);
@ -259,7 +259,7 @@ namespace HavenSoft.HexManiac.Tests {
public void AnchorCarriesSourceInformation() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 16, Height = 16 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 1);
viewPort.Edit("<000020>");
@ -271,7 +271,7 @@ namespace HavenSoft.HexManiac.Tests {
public void StartingAnAnchorAndGivingItNoNameClearsAnyAnchorNameAtThatPosition() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 1);
viewPort.Edit("<bob>");
@ -290,7 +290,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanRemoveAnchorWithNoReferences() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 2);
viewPort.Edit("^bob ^ ");
@ -302,7 +302,7 @@ namespace HavenSoft.HexManiac.Tests {
public void BackspaceClearsDataButNotFormats() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 1);
viewPort.Edit("01 02 03 04"); // 2x4 characters to clear
@ -325,7 +325,7 @@ namespace HavenSoft.HexManiac.Tests {
public void WritingOverTwoPointersWorks() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 1);
viewPort.Edit("<000020>");
@ -353,7 +353,7 @@ namespace HavenSoft.HexManiac.Tests {
public void PointerToUnknownLocationShowsUpDifferent() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(2, 1);
viewPort.Edit("<bob>");
@ -367,7 +367,7 @@ namespace HavenSoft.HexManiac.Tests {
public void AddingANewNamedPointerToNoLocationOverExistingNamedPointerToNoLocationWorks() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(2, 1);
viewPort.Edit("<bob>");
@ -382,7 +382,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanGotoAnchorName() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
int errorCalls = 0;
viewPort.OnError += (sender, e) => errorCalls++;
@ -398,7 +398,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanFindPointer() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(4, 1);
viewPort.Edit("<000058> 23 19");
@ -411,7 +411,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanUsePointerAsLink() {
var buffer = new byte[0x200];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(4, 1);
viewPort.Edit("<000120>");
@ -424,7 +424,7 @@ namespace HavenSoft.HexManiac.Tests {
public void FindAllSourcesWorks() {
var buffer = new byte[0x200];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
var editor = new EditorViewModel(new StubFileSystem());
editor.Add(viewPort);
@ -441,7 +441,7 @@ namespace HavenSoft.HexManiac.Tests {
public void NewAnchorWithSameNameMovesPointersToNewAnchor() {
var buffer = new byte[0x200];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
// put some pointers in the file
viewPort.SelectionStart = new Point(4, 1);
@ -465,7 +465,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanCopyAndPastePointers() {
var buffer = new byte[0x200];
var fileSystem = new StubFileSystem();
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), new PokemonModel(buffer)) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", new PokemonModel(buffer)) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0, 2);
@ -495,7 +495,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = new byte[0x200];
var model = new PokemonModel(buffer);
var fileSystem = new StubFileSystem();
var viewPort = new ViewPort(new LoadedFile("file.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("<null>");
viewPort.SelectionStart = new Point(0, 0);
@ -521,7 +521,7 @@ namespace HavenSoft.HexManiac.Tests {
public void ArrowMovementWhileTypingAnchorRevertsChange() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob"); // no trailing space: still under edit
@ -534,7 +534,7 @@ namespace HavenSoft.HexManiac.Tests {
public void EscapeWhileTypingAnchorCancelsChange() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob"); // no trailing space: still under edit
viewPort.Edit(ConsoleKey.Escape);
@ -547,7 +547,7 @@ namespace HavenSoft.HexManiac.Tests {
public void StartingAnAnchorOverAnAnchorClearsTheExistingAnchorInfo() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob ");
Assert.Equal("^bob", viewPort.AnchorText);
@ -564,7 +564,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
model.ObserveAnchorWritten(new ModelDelta(), "bob", new NoInfoRun(0x08));
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0x08, 0);
@ -576,7 +576,7 @@ namespace HavenSoft.HexManiac.Tests {
public void AnchorEditTextUpdatesWhenTypingAnAnchor() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^partialTe"); // in the middle of typing 'partialText'
@ -589,7 +589,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
model.ObserveAnchorWritten(new ModelDelta(), "bob", new NoInfoRun(0x08));
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0x08, 0);
viewPort.AnchorText = "^bob\"\"";
@ -602,7 +602,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
model.ObserveAnchorWritten(new ModelDelta(), "bob", new NoInfoRun(0x08));
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0x08, 0);
viewPort.AnchorText = "tom\"\"";
@ -618,7 +618,7 @@ namespace HavenSoft.HexManiac.Tests {
model.ObserveRunWritten(new ModelDelta(), new PointerRun(0x010));
model.WritePointer(new ModelDelta(), 0x014, 0x120);
model.ObserveRunWritten(new ModelDelta(), new PointerRun(0x014));
var viewPort = new ViewPort(new LoadedFile("test.txt", data), model) { Width = 0x8, Height = 0x8 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x8, Height = 0x8 };
viewPort.SelectionStart = new Point(0, 2); // 0x010
viewPort.Edit("00"); // this should remove the first pointer
@ -631,7 +631,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CreatingAnOffsetPointerShouldCoerceToTheStartOfExistingPointer() {
var data = new byte[0x200];
var model = new PokemonModel(data);
var viewPort = new ViewPort(new LoadedFile("test.txt", data), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("<000100>");
viewPort.SelectionStart = new Point(2, 0);
@ -647,7 +647,7 @@ namespace HavenSoft.HexManiac.Tests {
var errors = new List<string>();
var data = new byte[0x200];
var model = new PokemonModel(data);
var viewPort = new ViewPort(new LoadedFile("test.txt", data), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.OnError += (sender, message) => errors.Add(message);
viewPort.Edit("<000400>");
@ -659,7 +659,7 @@ namespace HavenSoft.HexManiac.Tests {
public void ClearingAPointerAlsoRemovesItsAnchor() {
var data = new byte[0x200];
var model = new PokemonModel(data);
var viewPort = new ViewPort(new LoadedFile("test.txt", data), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("<000100>");
model.ClearFormat(new ModelDelta(), 0x00, 4);
@ -671,7 +671,7 @@ namespace HavenSoft.HexManiac.Tests {
public void TypingBracesOnDataTriesToInterpretThatDataAsPointer() {
var data = new byte[0x200];
var model = new PokemonModel(data);
var viewPort = new ViewPort(new LoadedFile("test.txt", data), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("00 01 00 08");
viewPort.SelectionStart = new Point(0, 0);
@ -684,7 +684,7 @@ namespace HavenSoft.HexManiac.Tests {
public void StartingPointerEditAndThenMovingClearsAllEditedCells() {
var data = new byte[0x200];
var model = new PokemonModel(data);
var viewPort = new ViewPort(new LoadedFile("test.txt", data), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("<");
viewPort.SelectionStart = new Point(2, 2);
@ -704,7 +704,7 @@ namespace HavenSoft.HexManiac.Tests {
model.WritePointer(change, 0x23, 0x050); // a pointer that isn't 4-byte aligned, pointing to data that is
model.WritePointer(change, 0x10, 0x087); // a pointer that is 4-byte aligned, but pointing to something that isn't
model.WritePointer(change, 2, 0xA2); // a pointer that isn't 4-byte aligned, pointing to something not 4-byte aligned
var viewPort = new ViewPort(new LoadedFile("test.txt", data), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
// got to 50 and write an anchor
viewPort.SelectionStart = new Point(0x0, 0x5);

View File

@ -28,7 +28,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanWriteString() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x100).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model);
var viewPort = new ViewPort("test.txt", model);
viewPort.Edit("^bob\"\" \"Hello World!\"");
@ -54,7 +54,7 @@ namespace HavenSoft.HexManiac.Tests {
public void TryingToWriteStringFormatToNonStringFormatDataFails() {
var buffer = new byte[0x100];
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model);
var viewPort = new ViewPort("test.txt", model);
var editor = new EditorViewModel(new StubFileSystem());
editor.Add(viewPort);
@ -66,7 +66,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanTruncateString() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x100).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Hello World!\"");
@ -89,7 +89,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanAutoMoveWhenHittingAnchor() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x300).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(8, 0);
viewPort.Edit("^bob FF FF FF FF <tom>");
@ -114,7 +114,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanAutoMoveWhenHittingData() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(8, 0);
viewPort.Edit("A1 B3 64 18 <tom>");
@ -140,7 +140,7 @@ namespace HavenSoft.HexManiac.Tests {
public void AnchorWithNoNameIsNotValidIfNothingPointsToIt() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
var errors = new List<string>();
viewPort.OnError += (sender, e) => errors.Add(e);
@ -160,7 +160,7 @@ namespace HavenSoft.HexManiac.Tests {
public void OpeningStringFormatIncludesOpeningQuote() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Hello World!\"");
var anchor = (Anchor)viewPort[0, 0].Format;
@ -173,7 +173,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
for (int i = 0; i < 0x10; i++) buffer[i] = 0x00;
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
var errors = new List<string>();
viewPort.OnError += (sender, e) => errors.Add(e);
@ -196,7 +196,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
for (int i = 0; i < 0x10; i++) buffer[i] = 0x00;
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
// add an anchor with some data on the 2nd line
viewPort.SelectionStart = new Point(0, 1);
@ -212,7 +212,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
for (int i = 0; i < 0x10; i++) buffer[i] = 0x00;
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Some Content \\\\03More Content\"");
@ -225,7 +225,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
for (int i = 0; i < 0x10; i++) buffer[i] = 0x00;
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
var fileSystem = new StubFileSystem();
viewPort.Edit("^bob\"\" \"Hello World!\"");
@ -241,7 +241,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
for (int i = 0; i < 0x10; i++) buffer[i] = 0x00;
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Text and BULBASAUR!\"");
var results = viewPort.Find("\"bulbasaur\"");
@ -254,7 +254,7 @@ namespace HavenSoft.HexManiac.Tests {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
for (int i = 0; i < 0x10; i++) buffer[i] = 0x00;
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Text and BULBASAUR!\"");
var results = viewPort.Find("bulbasaur");
@ -272,7 +272,7 @@ namespace HavenSoft.HexManiac.Tests {
buffer[3] = 0x08;
Array.Copy(bytes, 0, buffer, 0x08, bytes.Length);
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0x08, 0);
viewPort.Edit("^");
@ -291,7 +291,7 @@ namespace HavenSoft.HexManiac.Tests {
buffer[3] = 0x08;
Array.Copy(bytes, 0, buffer, 0x08, bytes.Length);
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0x08, 0);
viewPort.Edit("^");
@ -306,7 +306,7 @@ namespace HavenSoft.HexManiac.Tests {
var bytes = PCSString.Convert("Hello World!").ToArray();
Array.Copy(bytes, 0, buffer, 0x08, bytes.Length);
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0x08, 0);
viewPort.Edit("^bob ");
@ -326,7 +326,7 @@ namespace HavenSoft.HexManiac.Tests {
buffer[2] = 0x00;
buffer[3] = 0x08;
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.SelectionStart = new Point(0x0C, 0);
viewPort.Edit(ConsoleKey.Backspace);
@ -350,5 +350,40 @@ namespace HavenSoft.HexManiac.Tests {
Assert.Equal(int.MaxValue, model.GetNextRun(0).Start);
}
[Fact]
public void StringSearchAutomaticallySearchesForPointersToResults() {
var text = "This is the song that never ends.";
var bytes = PCSString.Convert(text).ToArray();
var buffer = new byte[0x200];
Array.Copy(bytes, 0, buffer, 0x32, bytes.Length); // the data itself, positioned at x32 (won't be automatically found on load)
Array.Copy(new byte[] { 0x32, 0, 0, 0x08 }, 0, buffer, 0x10, 4); // the pointer to the data. Pointer is aligned, but data is not.
var model = new PokemonModel(buffer);
var viewPort = new ViewPort("test.gba", model);
// the act of searching should find the anchor
var results = viewPort.Find("this is the song");
Assert.Single(results);
Assert.Single(model.GetNextRun(0x32).PointerSources);
}
[Fact]
public void UnnamedStringAnchorAutomaticallySearchesForPointersToAnchor() {
var text = "This is the song that never ends.";
var bytes = PCSString.Convert(text).ToArray();
var buffer = new byte[0x200];
Array.Copy(bytes, 0, buffer, 0x32, bytes.Length); // the data itself, positioned at x32 (won't be automatically found on load)
Array.Copy(new byte[] { 0x32, 0, 0, 0x08 }, 0, buffer, 0x10, 4); // the pointer to the data. Pointer is aligned, but data is not.
var model = new PokemonModel(buffer);
var viewPort = new ViewPort("test.gba", model) { Width = 0x10, Height = 0x10 };
// the act of dropping an anchor should search for pointers
viewPort.SelectionStart = new Point(2, 3);
viewPort.Edit("^\"\" ");
Assert.Equal(0x32, model.GetNextRun(0x32).Start);
Assert.Single(model.GetNextRun(0x32).PointerSources);
}
}
}

View File

@ -21,7 +21,7 @@ namespace HavenSoft.HexManiac.Tests {
public void StringToolCanOpenOnChosenData() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Some Text\" 00 <000100>");
var toolProperties = new List<string>();
viewPort.Tools.PropertyChanged += (sender, e) => toolProperties.Add(e.PropertyName);
@ -35,7 +35,7 @@ namespace HavenSoft.HexManiac.Tests {
public void StringToolEditsAreReflectedInViewPort() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Some Text\" 00 <000100>");
viewPort.Tools.StringTool.Address = 0;
@ -48,7 +48,7 @@ namespace HavenSoft.HexManiac.Tests {
public void StringToolCanMoveData() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Some Text\" 00 <000100>");
var toolProperties = new List<string>();
viewPort.Tools.StringTool.PropertyChanged += (sender, e) => toolProperties.Add(e.PropertyName);
@ -63,7 +63,7 @@ namespace HavenSoft.HexManiac.Tests {
public void ViewPortMovesWhenStringToolMovesData() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Some Text\" 00 <000100>");
viewPort.Tools.StringTool.Address = 0;
@ -75,7 +75,7 @@ namespace HavenSoft.HexManiac.Tests {
public void StringToolMultiCharacterDeleteCleansUpUnusedBytes() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Some Text\" 00 <000100>");
viewPort.Tools.StringTool.Address = 0;
@ -100,7 +100,7 @@ namespace HavenSoft.HexManiac.Tests {
public void StringToolContentUpdatesWhenViewPortChange() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Some Text\"");
viewPort.SelectionStart = new Point(3, 0); // select the 'e' in 'Some'
@ -114,7 +114,7 @@ namespace HavenSoft.HexManiac.Tests {
public void ToolSelectionChangeUpdatesViewPortSelection() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("^bob\"\" \"Some Text\"");
viewPort.SelectionStart = new Point(3, 0);
viewPort.FollowLink(3, 0);

View File

@ -214,7 +214,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanExpandSelection() {
var data = new byte[0x200];
var model = new PokemonModel(data);
var viewPort = new ViewPort(new LoadedFile("test.txt", data), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("<000100>");
viewPort.SelectionStart = new Point(1, 0);

View File

@ -242,7 +242,7 @@ namespace HavenSoft.HexManiac.Tests {
[Fact]
public void CanClearData() {
var loadedFile = new LoadedFile("test", new byte[1000]);
var viewPort = new ViewPort(loadedFile, new PokemonModel(loadedFile.Contents)) { Width = 5, Height = 5 };
var viewPort = new ViewPort(loadedFile.Name, new PokemonModel(loadedFile.Contents)) { PreferredWidth = -1, Width = 5, Height = 5 };
viewPort.SelectionStart = new Point(0, 0);
viewPort.SelectionEnd = new Point(3, 3);
@ -302,7 +302,7 @@ namespace HavenSoft.HexManiac.Tests {
public void ClearRemovesFormats() {
var data = new byte[0x200];
var model = new PokemonModel(data);
var viewPort = new ViewPort(new LoadedFile("file.txt", data), model);
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
viewPort.Edit("<000100>");
viewPort.SelectionStart = new Point(2, 0);

View File

@ -303,7 +303,7 @@ namespace HavenSoft.HexManiac.Tests {
public void CanSaveAndLoadNamesAndFormats() {
var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
var model = new PokemonModel(buffer);
var viewPort = new ViewPort(new LoadedFile("test.txt", buffer), model) { Width = 0x10, Height = 0x10 };
var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
StoredMetadata metadata = null;
var fileSystem = new StubFileSystem { Save = (file, md) => { metadata = md; return true; } };
@ -311,7 +311,7 @@ namespace HavenSoft.HexManiac.Tests {
viewPort.Save.Execute(fileSystem);
var model2 = new PokemonModel(buffer, metadata);
var viewPort2 = new ViewPort(new LoadedFile("test.txt", buffer), model2) { Width = 0x10, Height = 0x10 };
var viewPort2 = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 };
Assert.Equal("bob", ((Anchor)viewPort2[0, 0].Format).Name);
}

View File

@ -42,7 +42,7 @@ namespace HavenSoft.HexManiac.WPF.Windows {
var loadedFile = fileSystem.LoadFile(fileName);
var metadata = fileSystem.MetadataFor(fileName);
var model = new AutoSearchModel(loadedFile.Contents, metadata);
editor.Add(new ViewPort(loadedFile, model));
editor.Add(new ViewPort(loadedFile.Name, model));
return editor;
}
}