예제 #1
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="start">Start position</param>
 /// <param name="end">End position</param>
 public HexBufferSpan(HexBufferPoint start, HexBufferPoint end)
 {
     if (start.Buffer != end.Buffer || start.Buffer == null)
     {
         throw new ArgumentException();
     }
     if (end.Position < start.Position)
     {
         throw new ArgumentOutOfRangeException(nameof(end));
     }
     Buffer = start.Buffer;
     Span   = HexSpan.FromBounds(start, end);
 }
예제 #2
0
 /// <summary>
 /// Gets information about a position in the stream
 /// </summary>
 /// <param name="position">Position</param>
 /// <param name="validSpan">Span of all valid data</param>
 /// <returns></returns>
 protected HexSpanInfo GetSpanInfo(HexPosition position, HexSpan validSpan)
 {
     if (position >= HexPosition.MaxEndPosition)
     {
         throw new ArgumentOutOfRangeException(nameof(position));
     }
     if (position >= validSpan.End)
     {
         return(new HexSpanInfo(HexSpan.FromBounds(validSpan.End, HexPosition.MaxEndPosition), HexSpanInfoFlags.None));
     }
     else if (position < validSpan.Start)
     {
         return(new HexSpanInfo(HexSpan.FromBounds(HexPosition.Zero, validSpan.Start), HexSpanInfoFlags.None));
     }
     else
     {
         return(new HexSpanInfo(validSpan, HexSpanInfoFlags.HasData));
     }
 }
예제 #3
0
파일: HexBuffer.cs 프로젝트: idkwim/dnSpy
        /// <summary>
        /// Gets the previous valid span or null if there's none left. This includes the input
        /// (<paramref name="position"/>) if it happens to lie within this valid span.
        /// This method merges all consecutive valid spans.
        /// </summary>
        /// <param name="position">Start position to check</param>
        /// <param name="lowerBounds">End position</param>
        /// <param name="fullSpan">true if positions after <paramref name="position"/> should be included
        /// in the returned result. This could result in worse performance.</param>
        /// <returns></returns>
        public HexSpan?GetPreviousValidSpan(HexPosition position, HexPosition lowerBounds, bool fullSpan)
        {
            if (position >= HexPosition.MaxEndPosition)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }
            if (lowerBounds > HexPosition.MaxEndPosition)
            {
                throw new ArgumentOutOfRangeException(nameof(lowerBounds));
            }
            bool checkForwards = true;

            while (position >= lowerBounds)
            {
                var info = GetSpanInfo(position);
                if (info.HasData)
                {
                    var start = GetStartOfData(info.Span.Start, validData: true);
                    var end   = info.Span.End;
                    if (fullSpan && checkForwards)
                    {
                        while (end < HexPosition.MaxEndPosition)
                        {
                            info = GetSpanInfo(end);
                            if (!info.HasData)
                            {
                                break;
                            }
                            end = info.Span.End;
                        }
                    }
                    return(HexSpan.FromBounds(start, end));
                }
                checkForwards = false;
                position      = GetStartOfData(info.Span.Start, validData: false);
                if (position == HexPosition.Zero)
                {
                    break;
                }
                position = position - 1;
            }
            return(null);
        }
예제 #4
0
파일: HexBuffer.cs 프로젝트: idkwim/dnSpy
        /// <summary>
        /// Gets the next valid span or null if there's none left. This includes the input
        /// (<paramref name="position"/>) if it happens to lie within this valid span.
        /// This method merges all consecutive valid spans.
        /// </summary>
        /// <param name="position">Start position to check</param>
        /// <param name="upperBounds">End position</param>
        /// <param name="fullSpan">true if positions before <paramref name="position"/> should be included
        /// in the returned result. This could result in worse performance.</param>
        /// <returns></returns>
        public HexSpan?GetNextValidSpan(HexPosition position, HexPosition upperBounds, bool fullSpan)
        {
            if (position >= HexPosition.MaxEndPosition)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }
            if (upperBounds > HexPosition.MaxEndPosition)
            {
                throw new ArgumentOutOfRangeException(nameof(upperBounds));
            }
            bool checkBackwards = true;

            while (position < upperBounds)
            {
                var info = GetSpanInfo(position);
                if (info.HasData)
                {
                    var start = info.Span.Start;
                    var end   = info.Span.End;
                    // We use MaxEndPosition and not upperBounds here since we must merge
                    // all consecutive spans even if some of them happen to be outside the
                    // requested range.
                    while (end < HexPosition.MaxEndPosition)
                    {
                        info = GetSpanInfo(end);
                        if (!info.HasData)
                        {
                            break;
                        }
                        end = info.Span.End;
                    }
                    if (fullSpan && checkBackwards)
                    {
                        start = GetStartOfData(start, validData: true);
                    }
                    return(HexSpan.FromBounds(start, end));
                }
                checkBackwards = false;
                position       = info.Span.End;
            }
            return(null);
        }
예제 #5
0
        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))));
            }
        }