Hallo
Ich hab da ein kleines Control gezeichnet, welches mir den HexDump eines Buffers anzeigt
#Feature
Strg-A - Markiert alles
Strg-C - Kopiert den Hex-Code
Strg-D - Entfernt alle markierungen
Page Up-Down - Scrollt eine page runter oder hoch
Pfeil-Tasten sind supportet.
Scrollen per maus
#Bugs
Scrollbar an der Seite - fixed from @RodFromGermany
# Quellcode - 04/11/2020 - 14:12
Spoiler anzeigen
#Bilder
aus dem Problemstellungsforum in den Sourcecodeaustausch verschoben ~VaporiZed
Ich hab da ein kleines Control gezeichnet, welches mir den HexDump eines Buffers anzeigt
#Feature
Strg-A - Markiert alles
Strg-C - Kopiert den Hex-Code
Strg-D - Entfernt alle markierungen
Page Up-Down - Scrollt eine page runter oder hoch
Pfeil-Tasten sind supportet.
Scrollen per maus
#Bugs
Scrollbar an der Seite - fixed from @RodFromGermany
# Quellcode - 04/11/2020 - 14:12
Quellcode
- using System;
- using System.Windows.Forms;
- using System.Runtime.InteropServices;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.ComponentModel;
- using System.Linq;
- using System.Threading;
- using System.Collections.Generic;
- using System.Runtime.CompilerServices;
- using System.Threading.Tasks;
- namespace _7dbg.UI
- {
- /*
- TODO:
- Scrollbar [/]
- Scrollen [x]
- Keys:
- Copy (STRG-C), [x]
- Select all (STRG-A), [x]
- Deselect all (STRG-D) [x]
- Number-Hover [x]
- Change
- Convert
- Suchen
- Mark [/]
- */
- [Docking(DockingBehavior.Ask)]
- class HexDump : Control
- {
- private static string s_offsetMask = IntPtr.Size == 4 ? "0x{0:X08}" : "0x{0:X016}";
- private static char[] s_asciiTable = new char[]
- {
- '.','.','.','.','.','.','.','.','.','.',
- '.','.','.','.','.','.','.','.','.','.',
- '.','.','.','.','.','.','.','.','.','.',
- '.','.','.','!','"','#','$','%','&','\'',
- '(',')','*','+',',','-','.','/','0','1',
- '2','3','4','5','6','7','8','9',':',';',
- '<','=','>','?','@','A','B','C','D','E',
- 'F','G','H','I','J','K','L','M','N','O',
- 'P','Q','R','S','T','U','V','W','X','Y',
- 'Z','[','\\',']','^','_','`','a','b','c',
- 'd','e','f','g','h','i','j','k','l','m',
- 'n','o','p','q','r','s','t','u','v','w',
- 'x','y','z','{','|','}','~','.','€','.',
- '‚','ƒ','„','…','†','‡','ˆ','‰','Š','‹',
- 'Œ','.','Ž','.','.','‘','’','“','”','•',
- '–','—','˜','™','š','›','œ','.','ž','Ÿ',
- ' ','¡','¢','£','¤','¥','¦','§','¨','©',
- 'ª','«','¬','.','®','¯','°','±','²','³',
- '´','µ','¶','·','¸','¹','º','»','¼','½',
- '¾','¿','À','Á','Â','Ã','Ä','Å','Æ','Ç',
- 'È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ',
- 'Ò','Ó','Ô','Õ','Ö','×','Ø','Ù','Ú','Û',
- 'Ü','Ý','Þ','ß','à','á','â','ã','ä','å',
- 'æ','ç','è','é','ê','ë','ì','í','î','ï',
- 'ð','ñ','ò','ó','ô','õ','ö','÷','ø','ù', // 240
- 'ú','û','ü','ý','þ','ÿ','Ā', // 250
- };
- #region Control Props
- // Later user
- private int _height;
- private int _width;
- #endregion
- private Color _DefaultSelectionBackground = Color.Transparent;
- private Color _SelectionBackground = Color.DodgerBlue;
- /// <summary>
- /// background color from seleted text
- /// </summary>
- public Color SelectionBackground
- {
- get => _SelectionBackground;
- set
- {
- if (_SelectionBackground == value) return;
- _SelectionBackground = value;
- Invalidate();
- }
- }
- #region Offset
- /// <summary>
- /// true: show the offset on left side. Otherwise hide the offset
- /// </summary>
- private bool _isOffsetEnabled;
- /// <summary>
- /// true: show the offset on left side. Otherwise hide the offset
- /// </summary>
- [Category("Layout")]
- public bool OffsetEnabled
- {
- get => _isOffsetEnabled;
- set
- {
- if (_isOffsetEnabled == value) return;
- _isOffsetEnabled = value;
- CalcXArea();
- Invalidate();
- }
- }
- /// <summary>
- /// The left and right space from offset text
- /// </summary>
- private (int Left, int Right) _offsetAreaPadding = (0, 8);
- /// <summary>
- /// The left and right space from offset text
- /// </summary>
- [Category("Layout")]
- public (int Left, int Right) OffsetAreaPadding
- {
- get => _offsetAreaPadding;
- set
- {
- if (_offsetAreaPadding.Left == Left && _offsetAreaPadding.Right == Right) return;
- _offsetAreaPadding = value;
- CalcXArea();
- Invalidate();
- }
- }
- #endregion
- private Color _selectedByteColor = Color.LimeGreen;
- /// <summary>
- /// max line displayable
- /// </summary>
- private int _lines;
- /// <summary>
- /// text size from a single hex value
- /// </summary>
- private Size _byteSize;
- /// <summary>
- /// text size from the offset text
- /// </summary>
- private Size _offsetAreaSize;
- /// <inheritdoc/>
- public override Font Font
- {
- get => base.Font;
- set
- {
- if (base.Font == value) return;
- base.Font = value;
- _asciiSize = TextRenderer.MeasureText(" ", Font);
- _byteSize = TextRenderer.MeasureText(" ", Font);
- _offsetAreaSize = TextRenderer.MeasureText(string.Format(s_offsetMask, 0), Font);
- CalcLinesPerPage();
- CalcXByteAreaWidth();
- CalcXArea();
- Invalidate();
- }
- }
- /// <summary>
- /// Data to display
- /// </summary>
- private byte[] _buffer;
- /// <summary>
- /// Handle to pinned data in memory
- /// </summary>
- private GCHandle _bufferHandle;
- /// <summary>
- /// Ptr to the pinned data in memory
- /// </summary>
- private IntPtr _bufferPtr;
- /// <summary>
- /// Offset for data to display
- /// </summary>
- private int _bufferOffset = 0;
- /// <summary>
- /// Start Offset for displaying bytes
- /// </summary>
- public int Offset
- {
- get => _bufferOffset;
- set
- {
- if (_bufferOffset == value) return;
- if (value >= Buffer.Length) throw new ArgumentOutOfRangeException("The offset must be smaller than the buffer length");
- if (value < 0) throw new ArgumentOutOfRangeException("The offset must be greater or equal to 0");
- _bufferOffset = value;
- Invalidate();
- }
- }
- /// <summary>
- /// Data to display
- /// </summary>
- [Category("Data")]
- public byte[] Buffer
- {
- get => _buffer;
- set
- {
- _buffer = value;
- if (_bufferHandle.IsAllocated) _bufferHandle.Free();
- _bufferHandle = GCHandle.Alloc(_buffer, GCHandleType.Pinned);
- _bufferPtr = _bufferHandle.AddrOfPinnedObject();
- CalcScrollbar();
- Invalidate();
- }
- }
- #region Dump
- /// <summary>
- /// start point for drawing the center area (byte display area)
- /// </summary>
- private int _xByteAreaOffset;
- /// <summary>
- /// the width from the center area (byte display area)
- /// </summary>
- private int _xByteAreaWidth;
- /// <summary>
- /// the current byte where mouse is hovered - lates
- /// </summary>
- private byte? _selectedByteValue;
- /// <summary>
- /// Bytes to displayed in a row
- /// </summary>
- private int _displayesBytes = 15;
- /// <summary>
- /// Bytes to displayed in a row
- /// </summary>
- [Category("Layout")]
- public int DisplayedBytes
- {
- get => _displayesBytes;
- set
- {
- if (_displayesBytes == value) return;
- if (value == 0) throw new ArgumentNullException(nameof(DisplayedBytes));
- _displayesBytes = value;
- CalcXByteAreaWidth();
- CalcXArea();
- CalcScrollbar();
- Invalidate();
- }
- }
- /// <summary>
- /// The left and right space from offset text
- /// </summary>
- private (int Left, int Right) _byteAreaPadding = (8, 8);
- /// <summary>
- /// The left and right space from offset text
- /// </summary>
- [Category("Layout")]
- public (int Left, int Right) BytePadding
- {
- get => _offsetAreaPadding;
- set
- {
- if (_byteAreaPadding.Left == Left && _byteAreaPadding.Right == Right) return;
- _byteAreaPadding = value;
- CalcXArea();
- Invalidate();
- }
- }
- #endregion
- #region Ascii
- /// <summary>
- /// size from a single ascii char
- /// </summary>
- private Size _asciiSize;
- /// <summary>
- /// start point for drawing the right area (ascii display area)
- /// </summary>
- private int _xAsciiAreaOffset;
- /// <summary>
- /// the width from the right area (ascii display area)
- /// </summary>
- private int _xAsciiAreaWidth;
- /// <summary>
- /// true: show the offset on right side. Otherwise hide the offset
- /// </summary>
- private bool _isAsciiEnabled;
- /// <summary>
- /// true: show the offset on right side. Otherwise hide the offset
- /// </summary>
- [Category("Layout")]
- public bool AsciiEnabled
- {
- get => _isAsciiEnabled;
- set
- {
- if (_isAsciiEnabled == value) return;
- _isAsciiEnabled = value;
- CalcXArea();
- Invalidate();
- }
- }
- /// <summary>
- /// The left and right space from offset text
- /// </summary>
- private (int Left, int Right) _AsciiAreaPadding = (8, 0);
- /// <summary>
- /// The left and right space from offset text
- /// </summary>
- [Category("Layout")]
- public (int Left, int Right) AsciiPadding
- {
- get => _offsetAreaPadding;
- set
- {
- if (_AsciiAreaPadding.Left == Left && _AsciiAreaPadding.Right == Right) return;
- _AsciiAreaPadding = value;
- CalcXArea();
- Invalidate();
- }
- }
- #endregion
- #region Scrollbar
- /// <summary>
- /// Descript if the content longer then the client can display
- /// </summary>
- private bool _isScrollbarNeeded;
- /// <summary>
- /// The client height - the thumb height
- /// </summary>
- private int _scrollArea;
- /// <summary>
- /// Byte to overjump by a single pixel scroll (up/down).
- /// </summary>
- private int _scrollSteps;
- /// <summary>
- /// the current y position from the thumb
- /// </summary>
- private int _scrollbarThumbY = 0;
- /// <summary>
- /// the final height of the thumb
- /// </summary>
- private int _scrollbarThumbHeight;
- /// <summary>
- /// the background color for the scrollbar
- /// </summary>
- private Color _scrollbarBackground = Color.FromArgb(30, 30, 30);
- /// <summary>
- /// the background brush for the scrollbar
- /// </summary>
- private SolidBrush _scrollbarBackgroundBrush = new SolidBrush(Color.FromArgb(30, 30, 30));
- /// <summary>
- /// Background color for the scrollbar
- /// </summary>
- [Category("Layout")]
- public Color ScrollBarBackground
- {
- get => _scrollbarBackground;
- set
- {
- if (_scrollbarBackground == value) return;
- _scrollbarBackground = value;
- Interlocked.Exchange(ref _scrollbarBackgroundBrush, new SolidBrush(_scrollbarBackground))?.Dispose();
- Invalidate();
- }
- }
- /// <summary>
- /// the foreground color for the scrollbar
- /// </summary>
- private Color _scrollbarForeground = Color.FromArgb(55, 55, 55);
- /// <summary>
- /// the foreground brush for the scrollbar
- /// </summary>
- private SolidBrush _scrollbarForegroundBrush = new SolidBrush(Color.FromArgb(55, 55, 55));
- /// <summary>
- /// Foreground color for the scrollbar
- /// </summary>
- [Category("Layout")]
- public Color ScrollBarForeground
- {
- get => _scrollbarForeground;
- set
- {
- if (_scrollbarForeground == value) return;
- _scrollbarForeground = value;
- Interlocked.Exchange(ref _scrollbarForegroundBrush, new SolidBrush(_scrollbarForeground))?.Dispose();
- Invalidate();
- }
- }
- /// <summary>
- /// Width from the scrollbar
- /// </summary>
- private int _scollbarWidth = 10;
- /// <summary>
- /// Width from the scrollbar
- /// </summary>
- [Category("Layout")]
- public int ScrollbarWidth
- {
- get => _scollbarWidth;
- set
- {
- if (_scollbarWidth == value) return;
- _scollbarWidth = value;
- Invalidate();
- }
- }
- /// <summary>
- /// min height from the scrollbar thumb
- /// </summary>
- private int _scrollbarThumbMinHeight = 30;
- /// <summary>
- /// Min height from the scrollbar thumb
- /// </summary>
- [Category("Layout")]
- public int ScrollbarThumbMinHeight
- {
- get => _scrollbarThumbMinHeight;
- set
- {
- if (_scrollbarThumbMinHeight == value) return;
- _scrollbarThumbMinHeight = value;
- Invalidate();
- }
- }
- #endregion
- #region Key Handling
- private bool _mouseOnScrollbarThumb = false;
- private int _mouseClickYOnScollbar = 0;
- private int? _selectionStartOffset;
- private int? _selectionEndOffset;
- private bool _mouseOnByteArea = false;
- private bool _mouseOnAsciiArea = false;
- #endregion
- public HexDump()
- {
- SetStyle(ControlStyles.UserPaint
- | ControlStyles.OptimizedDoubleBuffer
- | ControlStyles.Selectable
- | ControlStyles.UserMouse
- | ControlStyles.ResizeRedraw,
- true);
- SuspendLayout();
- Font = new Font(FontFamily.GenericMonospace, 10, FontStyle.Regular);
- BackColor = Color.FromArgb(45, 45, 45);
- ForeColor = Color.Silver;
- Buffer = Enumerable.Range(0, 500).Select(x => (byte)x).ToArray();
- ResumeLayout(false);
- }
- protected override void OnKeyDown(KeyEventArgs e)
- {
- if (e.KeyCode == Keys.C && e.Control)
- {
- if (_selectionStartOffset.HasValue && _selectionEndOffset.HasValue)
- {
- IEnumerable<byte> copyBuffer = Buffer.Skip(_selectionStartOffset.Value)
- .Take(_selectionEndOffset.Value - _selectionStartOffset.Value);
- string copyCode = string.Join(" ", copyBuffer.Select(x => x.ToString("X2")));
- Clipboard.SetText(copyCode);
- }
- }
- if (e.KeyCode == Keys.A && e.Control)
- {
- _selectionStartOffset = 0;
- _selectionEndOffset = Buffer.Length;
- }
- if (e.KeyCode == Keys.D && e.Control)
- {
- if (_selectionStartOffset.HasValue && _selectionEndOffset.HasValue)
- {
- _selectionStartOffset = null;
- _selectionEndOffset = null;
- }
- }
- if (e.KeyCode == Keys.Home)
- {
- Offset = 0;
- }
- if (e.KeyCode == Keys.End)
- {
- Offset = Buffer.Length - (int)(_lines * .5);
- }
- }
- protected override void OnMouseDown(MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Left)
- {
- if (Width - _scollbarWidth <= e.X
- && e.X <= Width
- && _scrollbarThumbY <= e.Y
- && e.Y <= _scrollbarThumbY + _scrollbarThumbHeight)
- {
- _mouseClickYOnScollbar = e.Y - _scrollbarThumbY;
- _mouseOnScrollbarThumb = true;
- }
- else if (_xByteAreaOffset <= e.X && e.X <= _xByteAreaOffset + _xByteAreaWidth)
- {
- _mouseOnByteArea = true;
- _selectionStartOffset = GetByteOffset(e.X, e.Y);
- _selectionEndOffset = null;
- }
- else if (_xAsciiAreaOffset <= e.X && e.X <= _xAsciiAreaOffset + _xAsciiAreaWidth)
- {
- _mouseOnAsciiArea = true;
- }
- }
- }
- protected override void OnMouseMove(MouseEventArgs e)
- {
- if (_mouseOnScrollbarThumb)
- {
- _scrollbarThumbY = e.Y - _mouseClickYOnScollbar;
- if (_scrollbarThumbY < 0)
- {
- _scrollbarThumbY = 0;
- }
- if (_scrollbarThumbY > Height - _scrollbarThumbMinHeight)
- {
- _scrollbarThumbY = Height - _scrollbarThumbMinHeight;
- }
- CalcScrollingFromPosition();
- Invalidate();
- }
- else if (_xByteAreaOffset <= e.X && e.X <= _xByteAreaOffset + _xByteAreaWidth)
- {
- if (_bufferHandle.IsAllocated)
- {
- int hoveredByteOffset = GetByteOffset(e.X, e.Y);
- if (hoveredByteOffset < 0)
- {
- hoveredByteOffset = 0;
- }
- else if (hoveredByteOffset > Buffer.Length)
- {
- hoveredByteOffset = Buffer.Length;
- }
- _selectedByteValue = Marshal.ReadByte(_bufferPtr + hoveredByteOffset);
- if (_selectionStartOffset.HasValue && _mouseOnByteArea)
- {
- _selectionEndOffset = GetByteOffset(e.X, e.Y);
- }
- }
- Invalidate();
- return;
- }
- }
- protected override void OnMouseUp(MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Left)
- {
- if (_mouseOnScrollbarThumb)
- {
- _mouseOnScrollbarThumb = false;
- }
- if (_mouseOnByteArea)
- {
- if (_selectionStartOffset.HasValue)
- {
- _selectionEndOffset = GetByteOffset(e.X, e.Y);
- }
- _mouseOnByteArea = false;
- }
- if (_mouseOnAsciiArea)
- {
- _mouseOnAsciiArea = false;
- }
- }
- }
- protected override void OnMouseWheel(MouseEventArgs e)
- {
- if (e.Delta > 0)
- {
- _bufferOffset -= 16;
- if (_bufferOffset < 0)
- {
- _bufferOffset = 0;
- }
- }
- else if (e.Delta < 0)
- {
- _bufferOffset += 16;
- if (_bufferOffset > Buffer.Length)
- {
- _bufferOffset = Buffer.Length;
- }
- }
- Invalidate();
- }
- protected override void OnSizeChanged(EventArgs e)
- {
- CalcLinesPerPage();
- CalcScrollbar();
- base.OnSizeChanged(e);
- _height = Height;
- _width = Width;
- }
- protected override void OnPaint(PaintEventArgs e)
- {
- if (_bufferPtr == IntPtr.Zero) return;
- e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
- //e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
- int xAreaOffset = 0;
- int bufferOffset = _bufferOffset;
- IntPtr bufferPtr = _bufferPtr;
- int? selectionStart = _selectionStartOffset;
- int? selectionEnd = _selectionEndOffset;
- bool selectionAvailable = selectionStart.HasValue && selectionEnd.HasValue;
- // check if selection available, true -> order
- if (selectionAvailable)
- {
- if (selectionEnd < selectionStart)
- {
- int? selectionTmpBuffer = selectionStart;
- selectionStart = selectionEnd;
- selectionEnd = selectionTmpBuffer;
- }
- }
- for (int iLine = 0; iLine < _lines + 1; iLine++)
- {
- if (bufferOffset >= _buffer.Length) break;
- DrawAtOffsetArea(e.Graphics, _offsetAreaPadding.Left, xAreaOffset, bufferOffset);
- int xByteAreaOffset = _xByteAreaOffset;
- int xAsciiAreaOffset = _xAsciiAreaOffset;
- for (int i = 0; i < _displayesBytes; i++)
- {
- byte value = Marshal.ReadByte(bufferPtr + bufferOffset);
- //byte value = _buffer[bufferOffset];
- string hexValue = value.ToString("X2");
- Color bgrColor = selectionAvailable
- && bufferOffset >= selectionStart.Value
- && bufferOffset <= selectionEnd.Value
- ? _SelectionBackground
- : _DefaultSelectionBackground;
- if (_selectedByteValue.HasValue && value == _selectedByteValue)
- {
- DrawAtByteArea(e.Graphics, xByteAreaOffset, xAreaOffset, _selectedByteColor, bgrColor, hexValue);
- DrawAtAsciiArea(e.Graphics, xAsciiAreaOffset, xAreaOffset, _selectedByteColor, bgrColor, s_asciiTable[value].ToString());
- }
- else
- {
- DrawAtByteArea(e.Graphics, xByteAreaOffset, xAreaOffset, ForeColor, bgrColor, hexValue);
- DrawAtAsciiArea(e.Graphics, xAsciiAreaOffset, xAreaOffset, ForeColor, bgrColor, s_asciiTable[value].ToString());
- }
- xByteAreaOffset += _byteSize.Width;
- xAsciiAreaOffset += _asciiSize.Width / 2;
- bufferOffset += 1;
- }
- xAreaOffset += _byteSize.Height;
- }
- if (_isScrollbarNeeded)
- {
- int xScrollbarOffset = Width - _scollbarWidth;
- e.Graphics.FillRectangle(_scrollbarBackgroundBrush, xScrollbarOffset, 0, _scollbarWidth, Height);
- e.Graphics.FillRectangle(_scrollbarForegroundBrush, xScrollbarOffset, _scrollbarThumbY, _scollbarWidth, _scrollbarThumbHeight);
- }
- }
- private void DrawAtOffsetArea(Graphics e, int xOffset, int yOffset, int value)
- {
- if (_isOffsetEnabled)
- {
- TextRenderer.DrawText(e, string.Format(s_offsetMask, value), Font, new Point(xOffset, yOffset), ForeColor, TextFormatFlags.Left);
- }
- }
- private void DrawAtByteArea(Graphics e, int xOffset, int yOffset, Color foreColor, Color backColor, string valueStrg)
- {
- TextRenderer.DrawText(e, valueStrg, Font, new Point(xOffset, yOffset), foreColor, backColor, TextFormatFlags.Left);
- }
- private void DrawAtAsciiArea(Graphics e, int xOffset, int yOffset, Color foreColor, Color backColor, string value)
- {
- if (_isAsciiEnabled)
- {
- TextRenderer.DrawText(e, value, Font, new Point(xOffset, yOffset), foreColor, backColor, TextFormatFlags.Left);
- }
- }
- private void CalcLinesPerPage()
- {
- _lines = Height / _byteSize.Height;
- CalcScrollbar();
- }
- private void CalcScrollbar()
- {
- if (_bufferHandle.IsAllocated)
- {
- _isScrollbarNeeded = Buffer.Length / _displayesBytes / _byteSize.Height > _lines;
- if (_isScrollbarNeeded)
- {
- // buffer.Length / _displayesBytes = maxlines => maxlines * _byteSize.Height = maxHeight
- int dumpHeightInPx = Buffer.Length / _displayesBytes * _byteSize.Height;
- _scrollbarThumbHeight = Height / dumpHeightInPx;
- if (_scrollbarThumbHeight < _scrollbarThumbMinHeight)
- {
- _scrollbarThumbHeight = _scrollbarThumbMinHeight;
- }
- int newScrollArea = Height - _scrollbarThumbHeight;
- if (_scrollArea != 0)
- {
- _scrollSteps = Buffer.Length / newScrollArea;
- _scrollbarThumbY = (int)Map(_scrollbarThumbY, 0, _scrollArea, 0, newScrollArea);
- }
- else
- {
- _scrollSteps = Buffer.Length / newScrollArea;
- }
- _scrollArea = newScrollArea;
- }
- }
- }
- private void CalcScrollingFromPosition()
- {
- _bufferOffset = _scrollSteps * _scrollbarThumbY;
- }
- private void CalcXArea()
- {
- _xByteAreaOffset = _isOffsetEnabled
- ? _offsetAreaPadding.Left + _offsetAreaSize.Width + _offsetAreaPadding.Right + /* 1 + */ _byteAreaPadding.Left
- : _xByteAreaOffset = _byteAreaPadding.Left;
- if (_isAsciiEnabled)
- {
- _xAsciiAreaOffset = _xByteAreaOffset + _xByteAreaWidth + _byteAreaPadding.Right + AsciiPadding.Left;
- _xAsciiAreaWidth = (int)(_asciiSize.Width * _displayesBytes * .5);
- }
- }
- private void CalcXByteAreaWidth()
- {
- _xByteAreaWidth = _displayesBytes * _byteSize.Width;
- }
- private int GetByteOffset(int mouseX, int mouseY)
- {
- int itemY = mouseY / _byteSize.Height;
- int itemX = ((mouseX - _xByteAreaOffset) / _byteSize.Width);
- return (itemY * _displayesBytes) + itemX + _bufferOffset;
- }
- private double Map(double value, double start1, double stop1, double start2, double stop2, bool withinBounds = true)
- {
- double newValue = (value - start1) / (stop1 - start1) * (stop2 - start2) + start2;
- if (!withinBounds)
- {
- return newValue;
- }
- if (start2 < stop2)
- {
- return Constrain(newValue, start2, stop2);
- }
- else
- {
- return Constrain(newValue, stop2, start2);
- }
- }
- private double Constrain(double n, double low, double high)
- {
- return System.Math.Max(System.Math.Min(n, high), low);
- }
- public bool FindFirst(byte[] src, out int? offset, int startOffset = 0, int endOffset = -1, bool failChecks = true)
- {
- InitSearch(src, startOffset, endOffset, out GCHandle srcHandle, out IntPtr srcPtr, failChecks);
- (bool Status, int? InnerOffset) result = Task.Run<(bool Status, int? Offset)>(() =>
- {
- int innerEndOffet = endOffset == -1
- ? Buffer.Length - src.Length
- : endOffset > Buffer.Length - src.Length
- ? Buffer.Length - src.Length
- : endOffset;
- byte firstSrcByte = Marshal.ReadByte(srcPtr);
- for (int i = startOffset; i < innerEndOffet; i++)
- {
- if (Marshal.ReadByte(_bufferPtr + i) == firstSrcByte)
- {
- if (IsSquenzEqual(_bufferPtr + i, srcPtr, src.Length))
- {
- return (true, i);
- }
- }
- }
- return (false, null);
- }).Result;
- srcHandle.Free();
- offset = result.InnerOffset;
- return result.Status;
- }
- public bool FindLast(byte[] src, out int? offset, int startOffset = 0, int endOffset = -1, bool failChecks = true)
- {
- InitSearch(src, startOffset, endOffset, out GCHandle srcHandle, out IntPtr srcPtr, failChecks);
- (bool Status, int? InnerOffset) result = Task.Run<(bool Status, int? Offset)>(() =>
- {
- int innerEndOffet = endOffset == -1
- ? Buffer.Length - src.Length
- : endOffset > Buffer.Length - src.Length
- ? Buffer.Length - src.Length
- : endOffset;
- byte firstSrcByte = Marshal.ReadByte(srcPtr);
- for (int i = innerEndOffet; i >= startOffset; i--)
- {
- if (Marshal.ReadByte(_bufferPtr + i) == firstSrcByte)
- {
- if (IsSquenzEqual(_bufferPtr + i, srcPtr, src.Length))
- {
- return (true, i);
- }
- }
- }
- return (false, null);
- }).Result;
- srcHandle.Free();
- offset = result.InnerOffset;
- return result.Status;
- }
- public int[] FindAll(byte[] src, int startOffset = 0, int endOffset = -1, bool failChecks = true)
- {
- InitSearch(src, startOffset, endOffset, out GCHandle srcHandle, out IntPtr srcPtr, failChecks);
- return Task.Run(() =>
- {
- List<int> offsets = new List<int>();
- int innerEndOffet = endOffset == -1
- ? Buffer.Length - src.Length
- : endOffset > Buffer.Length - src.Length
- ? Buffer.Length - src.Length
- : endOffset;
- byte firstSrcByte = Marshal.ReadByte(srcPtr);
- Parallel.For(startOffset, endOffset, i =>
- {
- if (Marshal.ReadByte(_bufferPtr + i) == firstSrcByte)
- {
- if (IsSquenzEqual(_bufferPtr + i, srcPtr, src.Length))
- {
- offsets.Add(i);
- }
- }
- });
- return offsets.ToArray();
- }).Result;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void InitSearch(byte[] srcBuffer, in int startOffset, in int endOffset, out GCHandle srcHandle, out IntPtr srcPtr, bool failChecks)
- {
- if (failChecks)
- {
- if (startOffset < 0)
- {
- throw new ArgumentOutOfRangeException("startOffset bust be bigger then 0");
- }
- if (endOffset != -1 && endOffset >= Buffer.Length)
- {
- throw new ArgumentOutOfRangeException("endOffset bust be smaller then the buffer length");
- }
- if (startOffset >= Buffer.Length)
- {
- throw new ArgumentOutOfRangeException("startOffset bust be smaller then the buffer length");
- }
- if (startOffset >= Buffer.Length)
- {
- throw new ArgumentOutOfRangeException("startOffset bust be smaller then the buffer length");
- }
- if (startOffset >= endOffset)
- {
- throw new ArgumentOutOfRangeException("startOffset bust be smaller then the endOffset");
- }
- }
- srcHandle = GCHandle.Alloc(srcBuffer, GCHandleType.Pinned);
- srcPtr = srcHandle.AddrOfPinnedObject();
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private bool IsSquenzEqual(IntPtr baseOffset, IntPtr srcPtr, int size)
- {
- for (int y = 1; y < size; y++)
- {
- if (Marshal.ReadByte(baseOffset + y) != Marshal.ReadByte(srcPtr + y))
- {
- return false;
- }
- }
- return true;
- }
- }
- }
#Bilder
aus dem Problemstellungsforum in den Sourcecodeaustausch verschoben ~VaporiZed
Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von „Facebamm“ ()