// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; using System.Diagnostics; using dnlib.IO; namespace dnlib.DotNet.MD { /// /// A MD table (eg. Method table) /// [DebuggerDisplay("DL:{dataReader.Length} R:{numRows} RS:{tableInfo.RowSize} C:{Count} {tableInfo.Name}")] public sealed class MDTable : IDisposable, IFileSection { readonly Table table; uint numRows; TableInfo tableInfo; DataReader dataReader; // Fix for VS2015 expression evaluator: "The debugger is unable to evaluate this expression" int Count => tableInfo.Columns.Length; /// public FileOffset StartOffset => (FileOffset)dataReader.StartOffset; /// public FileOffset EndOffset => (FileOffset)dataReader.EndOffset; /// /// Gets the table /// public Table Table => table; /// /// Gets the name of this table /// public string Name => tableInfo.Name; /// /// Returns total number of rows /// public uint Rows => numRows; /// /// Gets the total size in bytes of one row in this table /// public uint RowSize => (uint)tableInfo.RowSize; /// /// Returns all the columns /// public IList Columns => tableInfo.Columns; /// /// Returns true if there are no valid rows /// public bool IsEmpty => numRows == 0; /// /// Returns info about this table /// public TableInfo TableInfo => tableInfo; internal DataReader DataReader { get => dataReader; set => dataReader = value; } /// /// Constructor /// /// The table /// Number of rows in this table /// Info about this table internal MDTable(Table table, uint numRows, TableInfo tableInfo) { this.table = table; this.numRows = numRows; this.tableInfo = tableInfo; var columns = tableInfo.Columns; int length = columns.Length; if (length > 0) Column0 = columns[0]; if (length > 1) Column1 = columns[1]; if (length > 2) Column2 = columns[2]; if (length > 3) Column3 = columns[3]; if (length > 4) Column4 = columns[4]; if (length > 5) Column5 = columns[5]; if (length > 6) Column6 = columns[6]; if (length > 7) Column7 = columns[7]; if (length > 8) Column8 = columns[8]; } // So we don't have to call IList indexer internal readonly ColumnInfo Column0; internal readonly ColumnInfo Column1; internal readonly ColumnInfo Column2; internal readonly ColumnInfo Column3; internal readonly ColumnInfo Column4; internal readonly ColumnInfo Column5; internal readonly ColumnInfo Column6; internal readonly ColumnInfo Column7; internal readonly ColumnInfo Column8; /// /// Checks whether the row exists /// /// Row ID public bool IsValidRID(uint rid) => rid != 0 && rid <= numRows; /// /// Checks whether the row does not exist /// /// Row ID public bool IsInvalidRID(uint rid) => rid == 0 || rid > numRows; /// public void Dispose() { numRows = 0; tableInfo = null; dataReader = default; } } }