/* Copyright (C) 2014-2019 de4dot@gmail.com This file is part of dnSpy dnSpy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. dnSpy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with dnSpy. If not, see . */ using System; namespace dnSpy.Contracts.Hex { /// /// A span in a /// public readonly struct HexSpan : IEquatable { readonly HexPosition start, end; /// /// Gets a instance that covers everything from 0 to 2^64-1, inclusive /// public static readonly HexSpan FullSpan = new HexSpan(HexPosition.Zero, HexPosition.MaxEndPosition); /// /// true if this span covers everything from 0 to 2^64-1, inclusive /// public bool IsFull => start == HexPosition.Zero && end == HexPosition.MaxEndPosition; /// /// true if it's an empty span /// public bool IsEmpty => start == end; /// /// Gets the length /// public HexPosition Length => end - start; /// /// Gets the start of the span /// public HexPosition Start => start; /// /// Gets the end of the span /// public HexPosition End => end; // It's not public because public ctors should only take start and length params HexSpan(HexPosition start, HexPosition end) { if (start > end) throw new ArgumentOutOfRangeException(nameof(end)); if (end > HexPosition.MaxEndPosition) throw new ArgumentOutOfRangeException(nameof(end)); this.start = start; this.end = end; } /// /// Constructor /// /// Position /// Length public HexSpan(HexPosition start, ulong length) { if (start > HexPosition.MaxEndPosition) throw new ArgumentOutOfRangeException(nameof(start)); if ((start + length) > HexPosition.MaxEndPosition) throw new ArgumentOutOfRangeException(nameof(length)); this.start = start; end = start + length; } /// /// Creates a /// /// Start position /// End position /// public static HexSpan FromBounds(HexPosition start, HexPosition end) => new HexSpan(start, end); /// /// Returns true if lies within this span /// /// Span /// public bool Contains(HexSpan span) => span.Start >= Start && span.End <= End; /// /// Returns true if lies within this span /// /// Position /// public bool Contains(HexPosition position) => position >= Start && position < End; /// /// Returns the intersection or null if there's none /// /// Span /// public HexSpan? Intersection(HexSpan span) { var newStart = HexPosition.Max(Start, span.Start); var newEnd = HexPosition.Min(End, span.End); if (newStart <= newEnd) return FromBounds(newStart, newEnd); return null; } /// /// Returns true if intersects with this instance /// /// Span /// public bool IntersectsWith(HexSpan span) => Start <= span.End && End >= span.Start; /// /// Gets the overlap with or null if there's none /// /// Span /// public HexSpan? Overlap(HexSpan span) { var newStart = HexPosition.Max(Start, span.Start); var newEnd = HexPosition.Min(End, span.End); if (newStart < newEnd) return FromBounds(newStart, newEnd); return null; } /// /// Returns true if this instances overlaps with /// /// /// public bool OverlapsWith(HexSpan span) => Overlap(span) is not null; /// /// operator ==() /// /// Left /// Right /// public static bool operator ==(HexSpan left, HexSpan right) => left.Equals(right); /// /// operator !=() /// /// Left /// Right /// public static bool operator !=(HexSpan left, HexSpan right) => !left.Equals(right); /// /// Equals() /// /// Other instance /// public bool Equals(HexSpan other) => start == other.start && end == other.end; /// /// Equals() /// /// Other instance /// public override bool Equals(object? obj) => obj is HexSpan && Equals((HexSpan)obj); /// /// GetHashCode() /// /// public override int GetHashCode() => start.GetHashCode() ^ end.GetHashCode(); /// /// ToString() /// /// public override string ToString() => IsFull ? "[full]" : "[" + Start.ToString() + "," + End.ToString() + ")"; } }