/*
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");
}
}