public HexBufferLineFormatterImpl(HexBuffer buffer, HexBufferLineFormatterOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (options.CharsPerLine < 0) { throw new ArgumentOutOfRangeException(nameof(options)); } if (options.BytesPerLine < HexBufferLineFormatterOptions.MinBytesPerLine || options.BytesPerLine > HexBufferLineFormatterOptions.MaxBytesPerLine) { throw new ArgumentOutOfRangeException(nameof(options)); } if (options.GroupSizeInBytes < 0) { throw new ArgumentOutOfRangeException(nameof(options)); } if (options.OffsetFormat < HexBufferLineFormatterOptions.HexOffsetFormat_First || options.OffsetFormat > HexBufferLineFormatterOptions.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 < HexBufferLineFormatterOptions.MinOffsetBitSize || options.OffsetBitSize > HexBufferLineFormatterOptions.MaxOffsetBitSize) { throw new ArgumentOutOfRangeException(nameof(options)); } if (options.ValuesFormat < HexBufferLineFormatterOptions.HexValuesDisplayFormat_First || options.ValuesFormat > HexBufferLineFormatterOptions.HexValuesDisplayFormat_Last) { throw new ArgumentOutOfRangeException(nameof(options)); } this.buffer = buffer ?? throw new ArgumentNullException(nameof(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)HexBufferLineFormatterOptions.MaxBytesPerLine) { bytesPerLine = (ulong)(HexBufferLineFormatterOptions.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(); } CalculateColumnSpans(out var offsetSpan, out var valuesSpan, out var 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(); } }
public HexBufferLineFormatterImpl(HexBuffer buffer, HexBufferLineFormatterOptions 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 < HexBufferLineFormatterOptions.MinBytesPerLine || options.BytesPerLine > HexBufferLineFormatterOptions.MaxBytesPerLine) throw new ArgumentOutOfRangeException(nameof(options)); if (options.GroupSizeInBytes < 0) throw new ArgumentOutOfRangeException(nameof(options)); if (options.OffsetFormat < HexBufferLineFormatterOptions.HexOffsetFormat_First || options.OffsetFormat > HexBufferLineFormatterOptions.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 < HexBufferLineFormatterOptions.MinOffsetBitSize || options.OffsetBitSize > HexBufferLineFormatterOptions.MaxOffsetBitSize) throw new ArgumentOutOfRangeException(nameof(options)); if (options.ValuesFormat < HexBufferLineFormatterOptions.HexValuesDisplayFormat_First || options.ValuesFormat > HexBufferLineFormatterOptions.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)HexBufferLineFormatterOptions.MaxBytesPerLine) bytesPerLine = (ulong)(HexBufferLineFormatterOptions.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(); }