/* 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 { /// /// Contains a and a position /// public readonly struct HexBufferPoint : IEquatable, IComparable { /// /// true if this is a default instance that hasn't been initialized /// public bool IsDefault => Buffer is null; /// /// Gets the buffer /// public HexBuffer Buffer { get; } /// /// Gets the position /// public HexPosition Position { get; } /// /// Constructor /// /// Buffer /// Position public HexBufferPoint(HexBuffer buffer, HexPosition position) { if (position > HexPosition.MaxEndPosition) throw new ArgumentOutOfRangeException(nameof(position)); Buffer = buffer ?? throw new ArgumentNullException(nameof(buffer)); Position = position; } /// /// Converts to a /// /// Point public static implicit operator HexPosition(HexBufferPoint point) => point.Position; /// /// Gets the byte /// /// public byte GetByte() => Buffer.ReadByte(Position); /// /// Gets the or a value less than 0 if there's no data at /// /// public int TryGetByte() => Position >= HexPosition.MaxEndPosition ? -1 : Buffer.TryReadByte(Position); /// /// Add /// /// Value to add /// public HexBufferPoint Add(HexPosition value) => new HexBufferPoint(Buffer, Position + value); /// /// Subtract /// /// Value /// public HexBufferPoint Subtract(HexPosition value) => new HexBufferPoint(Buffer, Position - value); /// /// Returns the difference of with this instance /// /// Other instance /// public HexPosition Difference(HexBufferPoint other) => other - this; #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member public static HexPosition operator -(HexBufferPoint left, HexBufferPoint right) => left.Position - right.Position; public static HexBufferPoint operator -(HexBufferPoint point, HexPosition value) => point.Subtract(value); public static HexBufferPoint operator +(HexBufferPoint point, HexPosition value) => point.Add(value); public static bool operator ==(HexBufferPoint a, HexBufferPoint b) => a.Equals(b); public static bool operator !=(HexBufferPoint a, HexBufferPoint b) => !a.Equals(b); public static bool operator <(HexBufferPoint a, HexBufferPoint b) => a.CompareTo(b) < 0; public static bool operator <=(HexBufferPoint a, HexBufferPoint b) => a.CompareTo(b) <= 0; public static bool operator >(HexBufferPoint a, HexBufferPoint b) => a.CompareTo(b) > 0; public static bool operator >=(HexBufferPoint a, HexBufferPoint b) => a.CompareTo(b) >= 0; #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member /// /// Compares this instance with /// /// Ohter instance /// public int CompareTo(HexBufferPoint other) { if (Buffer != other.Buffer) throw new ArgumentException(); return Position.CompareTo(other.Position); } /// /// Equals() /// /// Other instance /// public bool Equals(HexBufferPoint other) => Buffer == other.Buffer && Position == other.Position; /// /// Equals() /// /// Object /// public override bool Equals(object? obj) => obj is HexBufferPoint && Equals((HexBufferPoint)obj); /// /// GetHashCode() /// /// public override int GetHashCode() => (Buffer?.GetHashCode() ?? 0) ^ Position.GetHashCode(); /// /// ToString() /// /// public override string ToString() { if (Buffer is null) return "uninit"; var b = TryGetByte(); var bs = b < 0 ? "??" : b.ToString("X2"); return Position.ToString() + "_'" + bs + "'"; } } }