private void AddTable(int source, string name, string format) { if (source < 0 || source > RawData.Length) { return; } var destination = ReadPointer(source); if (destination < 0 || destination > RawData.Length) { return; } var errorInfo = ArrayRun.TryParse(this, format, destination, null, out var arrayRun); if (!errorInfo.HasError) { ObserveAnchorWritten(noChangeDelta, name, arrayRun); } }
public void CanAddTextFormatToAnchorUsedOnlyByAnArray() { var changeToken = new ModelDelta(); var(model, viewPort) = (Model, ViewPort); WriteStrings(model.RawData, 0x10, "This is a song!"); ArrayRun.TryParse(model, "^[content<>]4", 0x00, null, out var array); model.WritePointer(changeToken, 0x04, 0x10); model.ObserveAnchorWritten(changeToken, "array", array); // there is a pointer at 0x00 that points to 0x10 // but we know about it via an array // at 0x10 is text // but we don't know that it's text ViewPort.Refresh(); viewPort.SelectionStart = new Point(0, 1); viewPort.Edit("^\"\" "); // adding the format should've stuck Assert.Empty(Errors); Assert.IsType <PCS>(viewPort[1, 1].Format); }
public void CustomHeadersWork() { var changeToken = new ModelDelta(); var(model, viewPort) = (Model, ViewPort); // arrange: setup the anchor used for the enums WriteStrings(model.RawData, 0x00, "cat", "bat", "bat", "sat"); ArrayRun.TryParse(model, "^[name\"\"4]4", 0x00, null, out var parentArray); model.ObserveAnchorWritten(changeToken, "parent", parentArray); ArrayRun.TryParse(model, "[a:: b:: c:: d::]parent", 0x20, null, out var childArray); model.ObserveAnchorWritten(changeToken, "child", childArray); ViewPort.Refresh(); // act/assert: check that the headers are the names when custom headers are turned on viewPort.UseCustomHeaders = true; Assert.Equal("cat", viewPort.Headers[2]); // act/assert: check that the headers are normal when custom headers are turned off viewPort.UseCustomHeaders = false; Assert.Equal("000020", viewPort.Headers[2]); }
public void ArraysWithInnerAnchorsRenderAnchors() { var(model, viewport) = (Model, ViewPort); var changeToken = new ModelDelta(); // arrange: setup data with a bunch of pointers pointing into an array of strings model.WritePointer(changeToken, 0x00, 0x80); model.ObserveRunWritten(changeToken, new PointerRun(0x00)); model.WritePointer(changeToken, 0x08, 0x84); model.ObserveRunWritten(changeToken, new PointerRun(0x08)); model.WritePointer(changeToken, 0x10, 0x88); model.ObserveRunWritten(changeToken, new PointerRun(0x10)); model.WritePointer(changeToken, 0x18, 0x8C); model.ObserveRunWritten(changeToken, new PointerRun(0x18)); // arrange: setup the array of strings WriteStrings(model.RawData, 0x80, "cat", "bat", "hat", "sat"); var existingAnchor = model.GetNextAnchor(0x80); ArrayRun.TryParse(model, "^[name\"\"4]4", 0x80, existingAnchor.PointerSources, out var arrayRun); model.ObserveAnchorWritten(changeToken, "sample", arrayRun); // arrange: create the viewmodel viewport.Refresh(); // assert: viewmodel renders anchors within the array // note that the strings are only 4 bytes long Assert.IsType <Anchor>(viewport[0, 8].Format); Assert.IsType <Anchor>(viewport[4, 8].Format); Assert.IsType <Anchor>(viewport[8, 8].Format); Assert.IsType <Anchor>(viewport[12, 8].Format); Assert.IsNotType <Anchor>(viewport[0, 9].Format); // assert: viewmodel renders pointers with names into the array Assert.Equal("sample", ((Pointer)viewport[0, 0].Format).DestinationName); Assert.Equal("sample/1", ((Pointer)viewport[8, 0].Format).DestinationName); Assert.Equal("sample/2", ((Pointer)viewport[0, 1].Format).DestinationName); Assert.Equal("sample/3", ((Pointer)viewport[8, 1].Format).DestinationName); }
public void ParentTableAutoMoveNotifies() { // Arrange SetFullModel(0x42); var(model, viewPort) = (Model, ViewPort); ArrayRun.TryParse(model, "[a: b:]8", 0x20, null, out var table); // parent table starts directly after child table model.ObserveAnchorWritten(new ModelDelta(), "parent", table); ArrayRun.TryParse(model, "[a: b:]parent", 0x00, null, out table); model.ObserveAnchorWritten(new ModelDelta(), "child", table); ViewPort.Refresh(); // Act viewPort.SelectionStart = new Point(0xD, 1); viewPort.Tools.SelectedIndex = viewPort.Tools.IndexOf(viewPort.Tools.TableTool); viewPort.Tools.TableTool.Append.Execute(); // Assert Assert.Equal(0, model.GetNextRun(0).Start); // the run being edit did not move Assert.Single(Messages); // user was notified about the other move }
public void ArraysSupportEditingEnums() { Model[0x42] = 2; // hat var changeToken = new ModelDelta(); var(model, viewPort) = (Model, ViewPort); // arrange: setup the anchor used for the enums WriteStrings(model.RawData, 0x00, "cat", "bat", "hat", "sat"); ArrayRun.TryParse(model, "^[name\"\"4]4", 0x00, null, out var arrayRun); model.ObserveAnchorWritten(changeToken, "sample", arrayRun); // arrange: setup the anchor with the data ArrayRun.TryParse(model, "[option.sample]4", 0x40, null, out arrayRun); model.ObserveAnchorWritten(changeToken, "data", arrayRun); // act: use a viewmodel to change 0x41 to 'bat' ViewPort.Refresh(); viewPort.SelectionStart = new Point(1, 4); // select space 0x41 viewPort.Edit("bat "); Assert.Equal(1, Model[0x41]); }
public void EditingStringToolEditsArray() { var changeToken = new ModelDelta(); var(model, viewPort) = (Model, ViewPort); WriteStrings(model.RawData, 100, "bobb", "tomm", "samm", "carr", "pall", "eggg"); model.WritePointer(changeToken, 200, 100); model.ObserveRunWritten(changeToken, new PointerRun(200)); ArrayRun.TryParse(model, "[word\"\"5]", 100, null, out var arrayRun); model.ObserveAnchorWritten(new ModelDelta(), "words", arrayRun); viewPort.FollowLink(0, 7); // 7*16 = 112, right in the middle of our data var writer = new StringBuilder(); writer.AppendLine(viewPort.Tools.StringTool.Content); writer.Append("carl"); viewPort.Tools.StringTool.Content = writer.ToString(); Assert.Equal(7 * 5, model.GetNextRun(100).Length); }
public void SupportNestedTextStreams() { // can parse var info = ArrayRun.TryParse(model, "[description<\"\">]4", 0, null, out var table); Assert.False(info.HasError); model.ObserveAnchorWritten(token, "table", table); // displays pointers viewPort.Goto.Execute("000100"); viewPort.Goto.Execute("000000"); Assert.IsType <Pointer>(viewPort[4, 0].Format); // can't update to point to non-text viewPort.SelectionStart = new Point(5, 0); errors.Clear(); viewPort.Edit("000100 "); // expected failure point Assert.Single(errors); // can update to point to text viewPort.SelectionStart = new Point(0, 4); viewPort.Edit("FF"); // have to put the FF first, or trying to create a text run will fail viewPort.SelectionStart = new Point(0, 4); viewPort.Edit("^text\"\" Hello World!\""); viewPort.SelectionStart = new Point(5, 0); errors.Clear(); viewPort.Edit("000040 "); Assert.Empty(errors); // can update to point to null viewPort.SelectionStart = new Point(5, 0); errors.Clear(); viewPort.Edit("null "); Assert.Empty(errors); }
public void CanEditToSecondEnumWithSameContent() { Model[0x42] = 3; // sat var changeToken = new ModelDelta(); var(model, viewPort) = (Model, ViewPort); // arrange: setup the anchor used for the enums WriteStrings(model.RawData, 0x00, "cat", "bat", "bat", "sat"); ArrayRun.TryParse(model, "^[name\"\"4]4", 0x00, null, out var arrayRun); model.ObserveAnchorWritten(changeToken, "sample", arrayRun); // arrange: setup the anchor with the data ArrayRun.TryParse(model, "[option.sample]4", 0x40, null, out arrayRun); model.ObserveAnchorWritten(changeToken, "data", arrayRun); // act: setup a viewmodel and change 0x41 to bat~2 ViewPort.Refresh(); viewPort.SelectionStart = new Point(1, 4); // select space 0x41 viewPort.Edit("bat~2 "); // assert: viewmodel should render bat~2 at 0x42 Assert.Equal(2, model.RawData[0x41]); }
public void MultipleEnumValuesWithSameContentAreDistinguishable() { Model[0x42] = 2; // bat~2 var changeToken = new ModelDelta(); var(model, viewPort) = (Model, ViewPort); // arrange: setup the anchor used for the enums WriteStrings(model.RawData, 0x00, "cat", "bat", "bat", "sat"); ArrayRun.TryParse(model, "^[name\"\"4]4", 0x00, null, out var arrayRun); model.ObserveAnchorWritten(changeToken, "sample", arrayRun); // arrange: setup the anchor with the data ArrayRun.TryParse(model, "[option.sample]4", 0x40, null, out arrayRun); model.ObserveAnchorWritten(changeToken, "data", arrayRun); // act: setup a viewmodel ViewPort.Refresh(); // assert: viewmodel should render bat~2 at 0x42 var format = (IntegerEnum)viewPort[2, 4].Format; Assert.Equal("bat~2", format.Value); }
public void HexSegment_Copy_CopyHexBytes() { var filesystem = new StubFileSystem(); ArrayRun.TryParse(Model, "[some: data:|h]4", 0, default, out var arrayRun);