internal ClrMetadataAccessor(PeDotNetInformation mdParent, Stream peStream, STORAGESTREAM streamInfo, long baseOffset) { _mdParent = mdParent; long offset = baseOffset + streamInfo.iOffset; long end = offset + streamInfo.iSize; peStream.Seek(offset, SeekOrigin.Begin); _md = new CMiniMdBase(peStream); _tables = new MetadataTableBase[_md.TableCount]; peStream.AlignToBytes(4); for (int i = 0; i < _tables.Length; i++) { ClrTable table = (ClrTable)i; Type recordType = _md[table].m_RecordType; Type tableType = typeof(MetadataTable <>).MakeGenericType(recordType); long startPosition = peStream.Position; long tableSize = _md[table].m_cbRec * _md.Schema.RowCount[table]; long expectedEnd = startPosition + tableSize; _tables[i] = (MetadataTableBase)Activator.CreateInstance(tableType, _md, table, peStream); Debug.Assert(peStream.Position == expectedEnd); } long diff = peStream.Position - end; Debug.Assert(diff == 0 || diff == -2 || diff == -4); ulong validBits = _md.Schema.TableValidityBits; for (int i = 0; i < _tables.Length; i++, validBits >>= 1) { if ((validBits & 1) != 0) { Debug.Assert(_tables[i].RowCount > 0, "used table has no rows."); } else { Debug.Assert(_tables[i].RowCount == 0, "unused table has rows."); } } }
protected MetadataTableBase(CMiniMdBase md, ClrTable table) { _md = md; Table = table; _tableDef = MetaModel.g_Tables[(int)table]; _tableDef = new CMiniTableDefEx( md[table], _tableDef.m_pColNames, _tableDef.m_pName ); _recordCount = md.Schema.RowCount[table]; }
private int SizeOfCodedToken(ClrCodedToken token) { CCodedTokenDef def = MetaModel.g_CodedTokens[(int)token]; int tagSize = CountBits(def.m_pTokens.Length - 1); foreach (var tableMdt in def.m_pTokens) { ClrTable table = tableMdt.GetTable(); int rowIdxSize = CountBits(Math.Max(m_Schema.RowCount[table], 1) - 1); if (tagSize + rowIdxSize > 16) { // one of the possible tables needs the 4 byte token. return(4); } } // we can index all possible tables with a 2-byte token. return(2); }
private int ColumnTypeSize(int type) { if (0 <= type && type <= MetaModel.iRidMax) { ClrTable table = (ClrTable)type; long rowCount = m_Schema.RowCount[table]; return((rowCount > 0xFFFF) ? 4 : 2); } else if (MetaModel.iCodedToken <= type && type <= MetaModel.iCodedTokenMax) { ClrCodedToken cdtkn = (ClrCodedToken)(type - MetaModel.iCodedToken); return(SizeOfCodedToken(cdtkn)); } else if (type == MetaModel.iBYTE) { return(1); } else if (type == MetaModel.iSHORT || type == MetaModel.iUSHORT) { return(2); } else if (type == MetaModel.iLONG || type == MetaModel.iULONG) { return(4); } else if (type == MetaModel.iSTRING) { return(m_Schema.StringIndexSize); } else if (type == MetaModel.iGUID) { return(m_Schema.GuidIndexSize); } else if (type == MetaModel.iBLOB) { return(m_Schema.BlobIndexSize); } throw new ArgumentException("Unexpected metadata field type."); }
public uint this[ClrTable table] { get { return(this[(uint)table]); } }
public CMiniTableDef this[ClrTable table] { get { return(m_TableDefs[(int)table]); } }
public MetadataTable(CMiniMdBase md, ClrTable table, Stream peStream) : base(md, table) { _items = ReadTable(peStream); }