public override HexBufferLineProvider Create(HexBuffer buffer, HexBufferLineProviderOptions options) { if (buffer == null) throw new ArgumentNullException(nameof(buffer)); if (options == null) throw new ArgumentNullException(nameof(options)); return new HexBufferLineProviderImpl(buffer, options); }
HexBufferLineProviderOptions GetHexBufferLineProviderOptions() { Debug.Assert(!double.IsNaN(lastFormattedLineSourceViewportWidth)); var options = new HexBufferLineProviderOptions(); options.CharsPerLine = (int)((lastFormattedLineSourceViewportWidth - FormattedLineSource.BaseIndentation) / FormattedLineSource.ColumnWidth); options.BytesPerLine = Options.GetBytesPerLine(); options.GroupSizeInBytes = Options.GetGroupSizeInBytes(); options.ShowOffset = Options.ShowOffsetColumn(); options.OffsetLowerCaseHex = Options.IsOffsetLowerCaseHexEnabled(); options.OffsetFormat = Options.GetOffsetFormat(); options.StartPosition = Options.GetStartPosition(); options.EndPosition = Options.GetEndPosition(); options.BasePosition = Options.GetBasePosition(); options.UseRelativePositions = Options.UseRelativePositions(); options.ShowValues = Options.ShowValuesColumn(); options.ValuesLowerCaseHex = Options.IsValuesLowerCaseHexEnabled(); options.OffsetBitSize = Options.GetOffsetBitSize(); options.ValuesFormat = Options.GetValuesDisplayFormat(); options.ShowAscii = Options.ShowAsciiColumn(); options.ColumnOrder = new HexColumnType[3] { HexColumnType.Offset, HexColumnType.Values, HexColumnType.Ascii }; const int DEFAULT_CHARS_PER_LINE = 80; if (options.CharsPerLine <= 0) options.CharsPerLine = DEFAULT_CHARS_PER_LINE; if (options.BytesPerLine < HexBufferLineProviderOptions.MinBytesPerLine) options.BytesPerLine = 0; else if (options.BytesPerLine > HexBufferLineProviderOptions.MaxBytesPerLine) options.BytesPerLine = HexBufferLineProviderOptions.MaxBytesPerLine; if (options.GroupSizeInBytes < 0) options.GroupSizeInBytes = 0; if (options.StartPosition >= HexPosition.MaxEndPosition) options.StartPosition = 0; if (options.EndPosition > HexPosition.MaxEndPosition) options.EndPosition = HexPosition.MaxEndPosition; if (options.StartPosition > options.EndPosition) options.StartPosition = options.EndPosition; if (options.BasePosition >= HexPosition.MaxEndPosition) options.BasePosition = 0; if (options.OffsetBitSize < HexBufferLineProviderOptions.MinOffsetBitSize) options.OffsetBitSize = HexBufferLineProviderOptions.MinOffsetBitSize; else if (options.OffsetBitSize > HexBufferLineProviderOptions.MaxOffsetBitSize) options.OffsetBitSize = HexBufferLineProviderOptions.MaxOffsetBitSize; if (options.OffsetFormat < HexBufferLineProviderOptions.HexOffsetFormat_First || options.OffsetFormat > HexBufferLineProviderOptions.HexOffsetFormat_Last) options.OffsetFormat = HexOffsetFormat.Hex; if (options.ValuesFormat < HexBufferLineProviderOptions.HexValuesDisplayFormat_First || options.ValuesFormat > HexBufferLineProviderOptions.HexValuesDisplayFormat_Last) options.ValuesFormat = HexValuesDisplayFormat.HexByte; return options; }
/// <summary> /// Creates a new <see cref="HexBufferLineProvider"/> instance /// </summary> /// <param name="buffer">Buffer</param> /// <param name="options">Options</param> /// <returns></returns> public abstract HexBufferLineProvider Create(HexBuffer buffer, HexBufferLineProviderOptions options);
public HexBufferLineProviderImpl(HexBuffer buffer, HexBufferLineProviderOptions options) { if (buffer == null) throw new ArgumentNullException(nameof(buffer)); if (options == null) throw new ArgumentNullException(nameof(options)); if (options.CharsPerLine < 0) throw new ArgumentOutOfRangeException(nameof(options)); if (options.BytesPerLine < HexBufferLineProviderOptions.MinBytesPerLine || options.BytesPerLine > HexBufferLineProviderOptions.MaxBytesPerLine) throw new ArgumentOutOfRangeException(nameof(options)); if (options.GroupSizeInBytes < 0) throw new ArgumentOutOfRangeException(nameof(options)); if (options.OffsetFormat < HexBufferLineProviderOptions.HexOffsetFormat_First || options.OffsetFormat > HexBufferLineProviderOptions.HexOffsetFormat_Last) throw new ArgumentOutOfRangeException(nameof(options)); if (options.StartPosition >= HexPosition.MaxEndPosition) throw new ArgumentOutOfRangeException(nameof(options)); if (options.EndPosition > HexPosition.MaxEndPosition) throw new ArgumentOutOfRangeException(nameof(options)); if (options.StartPosition > options.EndPosition) throw new ArgumentOutOfRangeException(nameof(options)); if (options.BasePosition >= HexPosition.MaxEndPosition) throw new ArgumentOutOfRangeException(nameof(options)); if (options.OffsetBitSize < HexBufferLineProviderOptions.MinOffsetBitSize || options.OffsetBitSize > HexBufferLineProviderOptions.MaxOffsetBitSize) throw new ArgumentOutOfRangeException(nameof(options)); if (options.ValuesFormat < HexBufferLineProviderOptions.HexValuesDisplayFormat_First || options.ValuesFormat > HexBufferLineProviderOptions.HexValuesDisplayFormat_Last) throw new ArgumentOutOfRangeException(nameof(options)); this.buffer = buffer; columnOrder = TryCreateColumns(options.ColumnOrder ?? defaultColumnOrders); if (columnOrder == null) throw new ArgumentOutOfRangeException(nameof(options)); cellList = new List<HexCell>(); useRelativePositions = options.UseRelativePositions; startPosition = options.StartPosition; endPosition = options.EndPosition; basePosition = options.BasePosition; showOffset = options.ShowOffset; showValues = options.ShowValues; showAscii = options.ShowAscii; valuesLowerCaseHex = options.ValuesLowerCaseHex; int bitSize = options.OffsetBitSize; if (bitSize == 0) bitSize = CalculateOffsetBitSize(); offsetFormatter = CreateOffsetFormatter(options.OffsetFormat, bitSize, options.OffsetLowerCaseHex); valueFormatter = valueFormatters[(int)options.ValuesFormat]; bytesPerLine = (ulong)options.BytesPerLine; if (bytesPerLine == 0) bytesPerLine = (ulong)CalculateBytesPerLine(options.CharsPerLine); if (bytesPerLine % (ulong)valueFormatter.ByteCount != 0) bytesPerLine = bytesPerLine - bytesPerLine % (ulong)valueFormatter.ByteCount + (ulong)valueFormatter.ByteCount; if (bytesPerLine > (ulong)HexBufferLineProviderOptions.MaxBytesPerLine) bytesPerLine = (ulong)(HexBufferLineProviderOptions.MaxBytesPerLine / valueFormatter.ByteCount * valueFormatter.ByteCount); if (bytesPerLine <= 0) throw new InvalidOperationException(); groupSizeInBytes = options.GroupSizeInBytes; if (groupSizeInBytes == 0) groupSizeInBytes = DEFAULT_GROUP_SIZE_IN_BYTES; if ((ulong)groupSizeInBytes > bytesPerLine) groupSizeInBytes = (int)bytesPerLine; groupSizeInBytes = (groupSizeInBytes + valueFormatter.ByteCount - 1) / valueFormatter.ByteCount * valueFormatter.ByteCount; if (groupSizeInBytes <= 0) throw new InvalidOperationException(); CharsPerLine = CalculateCharsPerLine(); stringBuilder = new StringBuilder(CharsPerLine); var totalBytes = options.EndPosition - options.StartPosition; Debug.Assert(totalBytes <= new HexPosition(1, 0)); if (totalBytes == 0) LineCount = 1; else if (bytesPerLine == 1) LineCount = totalBytes; else if (totalBytes == new HexPosition(1, 0)) { // 2^64 / x => (2^64 - x + x) / x => (2^64 - x) / x + 1 Debug.Assert(bytesPerLine > 1); ulong d = (0UL - bytesPerLine) / bytesPerLine + 1UL; ulong r = 0UL - (d * bytesPerLine); LineCount = d + (r == 0UL ? 0UL : 1UL); } else { ulong v = totalBytes.ToUInt64(); LineCount = v / bytesPerLine + (v % bytesPerLine == 0 ? 0UL : 1UL); } if (LineCount == 0) throw new InvalidOperationException(); VST.Span offsetSpan, valuesSpan, asciiSpan; CalculateColumnSpans(out offsetSpan, out valuesSpan, out asciiSpan); OffsetSpan = offsetSpan; ValuesSpan = valuesSpan; AsciiSpan = asciiSpan; var group = new List<HexGroupInformation>(); CalculateValuesGroupSpans(group); ValuesGroup = new ReadOnlyCollection<HexGroupInformation>(group.ToArray()); CalculateAsciiGroupSpans(group); AsciiGroup = new ReadOnlyCollection<HexGroupInformation>(group.ToArray()); if (ShowValues == ShowAscii && ValuesGroup.Count != AsciiGroup.Count) throw new InvalidOperationException(); }