/* 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 . */ // from dnlib using System; namespace dnSpy.Contracts.Hex.Files.DotNet { /// /// MetaData token /// public readonly struct MDToken : IEquatable, IComparable { /// /// Mask to get the rid from a raw metadata token /// public const uint RID_MASK = 0x00FFFFFF; /// /// Max rid value /// public const uint RID_MAX = RID_MASK; /// /// Number of bits to right shift a raw metadata token to get the table index /// public const int TABLE_SHIFT = 24; readonly uint token; /// /// Returns the table type /// public Table Table => ToTable(token); /// /// Returns the row id /// public uint Rid => ToRID(token); /// /// Returns the raw token /// public uint Raw => token; /// /// Returns true if it's a null token /// public bool IsNull => Rid == 0; /// /// Constructor /// /// Raw token public MDToken(uint token) => this.token = token; /// /// Constructor /// /// Raw token public MDToken(int token) : this((uint)token) { } /// /// Constructor /// /// The table type /// Row id public MDToken(Table table, uint rid) : this(((uint)table << TABLE_SHIFT) | rid) { } /// /// Constructor /// /// The table type /// Row id public MDToken(Table table, int rid) : this(((uint)table << TABLE_SHIFT) | (uint)rid) { } /// /// Returns the rid (row ID) /// /// A raw metadata token /// A rid public static uint ToRID(uint token) => token & RID_MASK; /// /// Returns the rid (row ID) /// /// A raw metadata token /// A rid public static uint ToRID(int token) => ToRID((uint)token); /// /// Returns the table /// /// A raw metadata token /// A metadata table index public static Table ToTable(uint token) => (Table)(token >> TABLE_SHIFT); /// /// Returns the table /// /// A raw metadata token /// A metadata table index public static Table ToTable(int token) => ToTable((uint)token); /// /// Gets the token as a raw 32-bit signed integer /// public int ToInt32() => (int)token; /// /// Gets the token as a raw 32-bit unsigned integer /// public uint ToUInt32() => token; /// Overloaded operator public static bool operator ==(MDToken left, MDToken right) { return left.CompareTo(right) == 0; } /// Overloaded operator public static bool operator !=(MDToken left, MDToken right) { return left.CompareTo(right) != 0; } /// Overloaded operator public static bool operator <(MDToken left, MDToken right) { return left.CompareTo(right) < 0; } /// Overloaded operator public static bool operator >(MDToken left, MDToken right) { return left.CompareTo(right) > 0; } /// Overloaded operator public static bool operator <=(MDToken left, MDToken right) { return left.CompareTo(right) <= 0; } /// Overloaded operator public static bool operator >=(MDToken left, MDToken right) { return left.CompareTo(right) >= 0; } /// public int CompareTo(MDToken other) => token.CompareTo(other.token); /// public bool Equals(MDToken other) => CompareTo(other) == 0; /// public override bool Equals(object? obj) { if (!(obj is MDToken)) return false; return Equals((MDToken)obj); } /// public override int GetHashCode() => (int)token; /// public override string ToString() => token.ToString("X8"); } }