Skip to content

Commit

Permalink
Refactor: IMemoryFormatterOutput interface
Browse files Browse the repository at this point in the history
The interface now renders individual memory bytes-as-text. This allows finer control of rendering, which will help when implementing #1232.

Fixed serious selection bugs in LowLevelViewInteractor and MemoryControl.
  • Loading branch information
uxmal committed Feb 1, 2023
1 parent ccdb4bc commit c6ec317
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 152 deletions.
6 changes: 4 additions & 2 deletions src/Arch/Pdp/Output/Word36MemoryFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ protected override void DoRenderUnit(Address addr, Constant c, IMemoryFormatterO
output.RenderUnit(addr, sUnit);
}

protected override string DoRenderAsText(ImageReader reader, int cUnits, Encoding enc)
protected override void DoRenderAsText(ImageReader reader, int cUnits, Encoding enc, IMemoryFormatterOutput output )
{
var rdr = (Word36ImageReader) reader;
var sb = new StringBuilder();
for (int i = 0; i < cUnits; ++i)
{
var addr = rdr.Address;
if (rdr.TryReadBeUInt36(out ulong value))
{
int shift = 4 * 7;
Expand All @@ -61,9 +62,10 @@ protected override string DoRenderAsText(ImageReader reader, int cUnits, Encodin
sb.Append(c);
shift -= 7;
}
output.RenderUnitAsText(addr, sb.ToString());
sb.Clear();
}
}
return sb.ToString();
}
}
}
12 changes: 8 additions & 4 deletions src/Core/Output/Dumper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,22 @@ public void RenderUnit(Address addr, string sUnit)
sbHex.Append(sUnit);
}

public void RenderUnitsAsText(int prePadding, string sBytes, int postPadding)
public void RenderUnitAsText(Address addr, string sUnit)
{
sb.Append(' ', prePadding + 1);
sb.Append(sBytes);
sb.Append(' ', postPadding);
sb.Append(sUnit);
}

public void RenderTextFillerSpan(int padding)
{
sb.Append(' ', padding);
}

public void EndLine(Constant [] chunks)
{
if (!HaveSameZeroBytes(prevLine, chunks))
{
stm.Write(sbHex.ToString());
stm.Write(' ');
stm.WriteLine(sb.ToString());
showEllipsis = true;
}
Expand Down
15 changes: 11 additions & 4 deletions src/Core/Output/IMemoryFormatterOutput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,21 @@ public interface IMemoryFormatterOutput
/// <summary>
/// Render a memory unit corresponding to the address <paramref name="addr"/>.
/// <param name="addr">The address of the memory unit.</param>
/// <param name="sUnit">The string representation of the memory unit.</param>
/// <param name="sUnit">The numeric representation of the memory unit.</param>
void RenderUnit(Address addr, string sUnit);

/// <summary>
/// Attempt to render the units as text, with a margin first.
/// Render the memory unit as text.
/// </summary>
/// <param name="sBytes"></param>
void RenderUnitsAsText(int prePadding, string sBytes, int postPadding);
/// <param name="addr">The address of the memory unit.</param>
/// <param name="sUnit">The text representation of the unit.</param>
void RenderUnitAsText(Address addr, string sUnit);

/// <summary>
/// Render the padding of the memory textual area.
/// </summary>
/// <param name="padding">Number of character positions to pad with.</param>
void RenderTextFillerSpan(int padding);

/// <summary>
/// Signals the end of the line.
Expand Down
32 changes: 17 additions & 15 deletions src/Core/Output/MemoryFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,12 @@ public bool RenderLine(EndianImageReader rdr, Encoding enc, IMemoryFormatterOutp
var offSaved = rdr.Offset;
var cb = offSaved - offStart;
rdr.Offset = offStart;
var sBytes = DoRenderAsText(rdr, (int)cb, enc);
rdr.Offset = offSaved;
output.RenderUnitsAsText(
prePaddingChunks * this.charsPerTextChunk,
sBytes,
postPaddingChunks * this.charsPerTextChunk);

output.RenderTextFillerSpan(prePaddingChunks * this.charsPerTextChunk);
DoRenderAsText(rdr, (int)cb, enc, output);
output.RenderTextFillerSpan(postPaddingChunks * this.charsPerTextChunk);
output.EndLine(chunksRead);

rdr.Offset = offSaved;
return moreData && rdr.IsValid;
}

Expand All @@ -170,21 +168,25 @@ protected virtual void DoRenderUnit(Address addr, Constant c, IMemoryFormatterOu
/// render.</param>
/// <param name="enc">The <see cref="Encoding"/> used to convert raw
/// memory to text.</param>
/// <returns>The resulting converted text.</returns>
protected virtual string DoRenderAsText(
/// <param name="output">The instance of <see cref="IMemoryFormatterOutput"/>
/// that renders the text chunks.</param>
protected virtual void DoRenderAsText(
ImageReader rdr,
int cUnits,
Encoding enc)
Encoding enc,
IMemoryFormatterOutput output)
{
var addr = rdr.Address;
var bytes = rdr.ReadBytes(cUnits);
var chars = enc.GetChars(bytes);
for (int i = 0; i < chars.Length; ++i)
for (int i = 0; i < bytes.Length; ++i)
{
char ch = chars[i];
char[] s = enc.GetChars(bytes, i, 1);
char ch = s[0];
if (char.IsControl(ch) || char.IsSurrogate(ch) || (0xE000 <= ch && ch <= 0xE0FF))
chars[i] = '.';
s[0] = '.';
output.RenderUnitAsText(addr, new string(s));
addr = addr + 1;
}
return new string(chars);
}

private static ulong Align(ulong ul, uint alignment)
Expand Down
10 changes: 5 additions & 5 deletions src/Gui/Services/ILowLevelViewService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ namespace Reko.Gui.Services
{
public class SelectionChangedEventArgs : EventArgs
{
private AddressRange range;

public SelectionChangedEventArgs(AddressRange range)
public SelectionChangedEventArgs(Address addrAnchor, Address addrEnd)
{
this.range = range;
this.Anchor = addrAnchor;
this.End = addrEnd;
}

public AddressRange AddressRange { get { return range; } }
public Address Anchor { get; }
public Address End { get; }
}

/// <summary>
Expand Down
14 changes: 10 additions & 4 deletions src/UnitTests/Arch/Pdp/Memory/Word36MemoryAreaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class Word36MemoryAreaTests
private class TestOutputDevice : IMemoryFormatterOutput
{
private readonly StringBuilder sb;
private int prepadding;

public TestOutputDevice()
{
Expand All @@ -45,6 +46,7 @@ public TestOutputDevice()

public void BeginLine()
{
prepadding = 1;
}

public void EndLine(Constant[] bytes)
Expand All @@ -68,11 +70,15 @@ public void RenderUnit(Address addr, string sUnit)
sb.Append(sUnit);
}

public void RenderUnitsAsText(int prePadding, string sBytes, int postPadding)
public void RenderTextFillerSpan(int padding)
{
sb.Append(' ', prePadding + 1);
sb.Append(sBytes);
sb.Append(' ', postPadding);
sb.Append(' ', padding + prepadding);
prepadding = 0;
}

public void RenderUnitAsText(Address addr, string sUnit)
{
sb.Append(sUnit);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@
#endregion

using Reko.Core;
using Reko.Core.Diagnostics;
using Reko.Core.Types;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace Reko.UserInterfaces.WindowsForms.Controls
{
Expand Down Expand Up @@ -172,13 +170,13 @@ private void RenderSelectionOverlay(
return;
var xBegin = (int) xSelectionBegin.Value;
var xEnd = (int) xSelectionEnd.Value;
Debug.WriteLine($"[{xBegin}-{xEnd}): min: {xMin}, max: {xMax}");
trace.Verbose($"[{xBegin}-{xEnd}): min: {xMin}, max: {xMax}");
if (xBegin >= xMax || xEnd < xMin)
return;
xBegin = Math.Max(xMin, xBegin);
xEnd = Math.Min(xMax, xEnd);
(xBegin, xEnd) = NormalizeSelection(xBegin, xEnd);
Debug.WriteLine($"Painting overlay: ({xBegin}, {xEnd-xBegin}, {y}, {height})");
trace.Verbose($"Painting overlay: ({xBegin}, {xEnd-xBegin}, {y}, {height})");
g.FillRectangle(brOverlay, CxScroll + xBegin, y, xEnd - xBegin, height);
}

Expand Down
7 changes: 5 additions & 2 deletions src/UserInterfaces/WindowsForms/Controls/ImageMapView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#endregion

using Reko.Core;
using Reko.Core.Diagnostics;
using Reko.Core.Types;
using System;
using System.Collections.Generic;
Expand All @@ -35,6 +36,8 @@ namespace Reko.UserInterfaces.WindowsForms.Controls

public partial class ImageMapView : Control
{
private static readonly TraceSwitch trace = new TraceSwitch(nameof(ImageMapView), "");

private const float ZoomOutFactor = 1.25F;
private const float ZoomInFactor = 4.0F / 5.0F;
private const int CySelection = 3;
Expand Down Expand Up @@ -126,7 +129,7 @@ public AddressRange SelectedRange
if (value == this.selectedRange)
return;
this.selectedRange = value;
Debug.WriteLine($"{nameof(ImageMapView)}: selected range {value}");
trace.Inform($"{nameof(ImageMapView)}: selected range {value}");
Invalidate();
}
}
Expand Down Expand Up @@ -292,7 +295,7 @@ private Address MapClientPositionToAddress(int x)

protected override void OnKeyDown(KeyEventArgs e)
{
Debug.WriteLine($"{nameof(ImageMapView)} KeyDown: {e.KeyData}");
trace.Inform($"{nameof(ImageMapView)} KeyDown: {e.KeyData}");
switch (e.KeyData)
{
case Keys.Add:
Expand Down
Loading

0 comments on commit c6ec317

Please sign in to comment.