public HexBufferLineImpl(HexBufferLineFormatter hexBufferLineFormatter, HexPosition lineNumber, ReadOnlyCollection<HexColumnType> columnOrder, HexBufferSpan bufferSpan, HexBytes hexBytes, string text, bool isOffsetColumnPresent, bool isValuesColumnPresent, bool isAsciiColumnPresent, HexPosition logicalOffset, HexCellCollection valueCells, HexCellCollection asciiCells, VST.Span offsetSpan, VST.Span fullValuesSpan, VST.Span visibleValuesSpan, VST.Span fullAsciiSpan, VST.Span visibleAsciiSpan) { if (hexBufferLineFormatter == null) throw new ArgumentNullException(nameof(hexBufferLineFormatter)); if (columnOrder == null) throw new ArgumentNullException(nameof(columnOrder)); if (bufferSpan.IsDefault) throw new ArgumentException(); if (hexBytes.IsDefault) throw new ArgumentException(); if (text == null) throw new ArgumentNullException(nameof(text)); if (valueCells.IsDefault) throw new ArgumentNullException(nameof(valueCells)); if (asciiCells.IsDefault) throw new ArgumentNullException(nameof(asciiCells)); LineProvider = hexBufferLineFormatter; LineNumber = lineNumber; ColumnOrder = columnOrder; BufferSpan = bufferSpan; HexBytes = hexBytes; Text = text; IsOffsetColumnPresent = isOffsetColumnPresent; IsValuesColumnPresent = isValuesColumnPresent; IsAsciiColumnPresent = isAsciiColumnPresent; LogicalOffset = logicalOffset; ValueCells = valueCells; AsciiCells = asciiCells; this.offsetSpan = offsetSpan; this.fullValuesSpan = fullValuesSpan; this.visibleValuesSpan = visibleValuesSpan; this.fullAsciiSpan = fullAsciiSpan; this.visibleAsciiSpan = visibleAsciiSpan; }
public HexBufferLineImpl(HexBufferLineFormatter hexBufferLineFormatter, HexPosition lineNumber, ReadOnlyCollection <HexColumnType> columnOrder, HexBufferSpan bufferSpan, HexBytes hexBytes, string text, bool isOffsetColumnPresent, bool isValuesColumnPresent, bool isAsciiColumnPresent, HexPosition logicalOffset, HexCellCollection valueCells, HexCellCollection asciiCells, VST.Span offsetSpan, VST.Span fullValuesSpan, VST.Span visibleValuesSpan, VST.Span fullAsciiSpan, VST.Span visibleAsciiSpan) { if (hexBufferLineFormatter == null) { throw new ArgumentNullException(nameof(hexBufferLineFormatter)); } if (columnOrder == null) { throw new ArgumentNullException(nameof(columnOrder)); } if (bufferSpan.IsDefault) { throw new ArgumentException(); } if (hexBytes.IsDefault) { throw new ArgumentException(); } if (text == null) { throw new ArgumentNullException(nameof(text)); } if (valueCells.IsDefault) { throw new ArgumentNullException(nameof(valueCells)); } if (asciiCells.IsDefault) { throw new ArgumentNullException(nameof(asciiCells)); } LineProvider = hexBufferLineFormatter; LineNumber = lineNumber; ColumnOrder = columnOrder; BufferSpan = bufferSpan; HexBytes = hexBytes; Text = text; IsOffsetColumnPresent = isOffsetColumnPresent; IsValuesColumnPresent = isValuesColumnPresent; IsAsciiColumnPresent = isAsciiColumnPresent; LogicalOffset = logicalOffset; ValueCells = valueCells; AsciiCells = asciiCells; this.offsetSpan = offsetSpan; this.fullValuesSpan = fullValuesSpan; this.visibleValuesSpan = visibleValuesSpan; this.fullAsciiSpan = fullAsciiSpan; this.visibleAsciiSpan = visibleAsciiSpan; }
void ClearCells(char[] chars, bool isColumnPresent, HexCellCollection cells, HexBufferSpan visibleBytes) { if (!isColumnPresent) return; foreach (var cell in cells.GetVisibleCells()) { // Don't clear it if the cell is in the visible bytes span, this includes the case // where only some of its bytes are visible. if (visibleBytes.Contains(cell.BufferSpan)) continue; for (int i = cell.TextSpan.Start; i < cell.TextSpan.End; i++) chars[i] = ' '; } }
static KeyValuePair<HexCell, int>? GetVisible(HexCellCollection collection, HexCell cell) { if (cell.HasData) throw new ArgumentException(); for (int i = cell.Index + 1; i < collection.Count; i++) { var c = collection[i]; if (!c.HasData) continue; return new KeyValuePair<HexCell, int>(c, 0); } for (int i = cell.Index - 1; i >= 0; i--) { var c = collection[i]; if (!c.HasData) continue; return new KeyValuePair<HexCell, int>(c, c.CellSpan.Length - 1); } return null; }
IEnumerable<TextAndHexSpan> GetTextAndHexSpans(bool isColumnPresent, HexCellCollection collection, HexBufferSpan span, HexSpanSelectionFlags flags, VST.Span visibleSpan, VST.Span fullSpan) { if (span.IsDefault) throw new ArgumentException(); if (span.Buffer != Buffer) throw new ArgumentException(); if (!isColumnPresent) yield break; var overlapSpan = BufferSpan.Overlap(span); if (overlapSpan == null) yield break; if ((flags & (HexSpanSelectionFlags.Group0 | HexSpanSelectionFlags.Group1)) != 0) { bool group0 = (flags & HexSpanSelectionFlags.Group0) != 0; bool group1 = (flags & HexSpanSelectionFlags.Group1) != 0; IEnumerable<HexCell> cells; if ((flags & HexSpanSelectionFlags.AllCells) != 0) { cells = collection.GetCells(); overlapSpan = BufferSpan; } else if ((flags & HexSpanSelectionFlags.AllVisibleCells) != 0) { cells = collection.GetVisibleCells(); overlapSpan = BufferSpan; } else cells = collection.GetCells(overlapSpan.Value); HexCell firstCell = null; HexCell lastCell = null; foreach (var cell in cells) { if (!((cell.GroupIndex == 0 && group0) || (cell.GroupIndex == 1 && group1))) continue; if (firstCell == null) { firstCell = cell; lastCell = cell; } else if (lastCell.Index + 1 == cell.Index && lastCell.GroupIndex == cell.GroupIndex) lastCell = cell; else { yield return Create(collection, firstCell, lastCell, overlapSpan.Value); firstCell = lastCell = cell; } } if (firstCell != null) yield return Create(collection, firstCell, lastCell, overlapSpan.Value); yield break; } if ((flags & HexSpanSelectionFlags.AllVisibleCells) != 0) { yield return new TextAndHexSpan(visibleSpan, BufferSpan); yield break; } if ((flags & HexSpanSelectionFlags.AllCells) != 0) { yield return new TextAndHexSpan(fullSpan, BufferSpan); yield break; } if ((flags & HexSpanSelectionFlags.OneValue) != 0) { foreach (var cell in collection.GetCells(overlapSpan.Value)) { if (!cell.HasData) continue; var cellSpan = cell.GetSpan(flags); yield return new TextAndHexSpan(cellSpan, new HexBufferSpan(Buffer, cell.BufferSpan)); } } else { int textStart = int.MaxValue; int textEnd = int.MinValue; var posStart = HexPosition.MaxValue; var posEnd = HexPosition.MinValue; foreach (var cell in collection.GetCells(overlapSpan.Value)) { if (!cell.HasData) continue; var cellSpan = cell.GetSpan(flags); textStart = Math.Min(textStart, cellSpan.Start); textEnd = Math.Max(textEnd, cellSpan.End); posStart = HexPosition.Min(posStart, cell.BufferStart); posEnd = HexPosition.Max(posEnd, cell.BufferEnd); } if (textStart > textEnd || posStart > posEnd) yield break; yield return new TextAndHexSpan(VST.Span.FromBounds(textStart, textEnd), new HexBufferSpan(Buffer, HexSpan.FromBounds(posStart, posEnd))); } }
TextAndHexSpan Create(HexCellCollection collection, HexCell first, HexCell last, HexBufferSpan bufferSpan) { var firstCellSpan = first.FullSpan; var lastCellSpan = last.FullSpan; var startPos = HexPosition.MaxEndPosition; var endPos = HexPosition.Zero; for (int i = first.Index; i <= last.Index; i++) { var cell = collection[i]; if (!cell.HasData) continue; startPos = HexPosition.Min(startPos, cell.BufferStart); endPos = HexPosition.Max(endPos, cell.BufferEnd); } var resultBufferSpan = startPos <= endPos ? new HexBufferSpan(new HexBufferPoint(Buffer, startPos), new HexBufferPoint(Buffer, endPos)) : bufferSpan; return new TextAndHexSpan(VST.Span.FromBounds(firstCellSpan.Start, lastCellSpan.End), resultBufferSpan); }