/// <summary> /// Find all rids that contain <paramref name="key"/> /// </summary> /// <param name="key">The key</param> /// <returns>A new <see cref="RidList"/> instance</returns> public RidList FindAllRows(uint key) { int startIndex = BinarySearch(key); if (startIndex == 0) { return(RidList.Empty); } int endIndex = startIndex + 1; for (; startIndex > 1; startIndex--) { if (key != rows[startIndex - 1].key) { break; } } for (; endIndex < rows.Length; endIndex++) { if (key != rows[endIndex].key) { break; } } var list = new RandomRidList(endIndex - startIndex); for (int i = startIndex; i < endIndex; i++) { list.Add(rows[i].rid); } return(list); }
/// <inheritdoc/> public override RidList GetExportedTypeRidList() { if (!hasDeletedRows) { return(base.GetExportedTypeRidList()); } uint rows = tablesStream.ExportedTypeTable.Rows; var list = new RandomRidList((int)rows); for (uint rid = 1; rid <= rows; rid++) { var row = tablesStream.ReadExportedTypeRow(rid); if (row == null) { continue; // Should never happen since rid is valid } // RTSpecialName is ignored by the CLR. It's only the name that indicates // whether it's been deleted. if (stringsStream.ReadNoNull(row.TypeName).StartsWith(DeletedName)) { continue; // ignore this deleted row } list.Add(rid); } return(list); }
/// <inheritdoc/> public override RidList GetPropertyRidList(uint propertyMapRid) { var list = GetRidList(tablesStream.PropertyMapTable, propertyMapRid, 1, tablesStream.PropertyTable); if (list.Length == 0 || (!hasPropertyPtr && !hasDeletedRows)) { return(list); } var destTable = tablesStream.PropertyTable; var newList = new RandomRidList((int)list.Length); for (uint i = 0; i < list.Length; i++) { var rid = ToPropertyRid(list[i]); if (destTable.IsInvalidRID(rid)) { continue; } if (hasDeletedRows) { // It's a deleted row if RTSpecialName is set and name is "_Deleted" var row = tablesStream.ReadPropertyRow(rid); if (row == null) { continue; // Should never happen since rid is valid } if ((row.PropFlags & (uint)PropertyAttributes.RTSpecialName) != 0) { if (stringsStream.ReadNoNull(row.Name).StartsWith(DeletedName)) { continue; // ignore this deleted row } } } // It's a valid non-deleted rid so add it newList.Add(rid); } return(newList); }
/// <inheritdoc/> public override RidList GetParamRidList(uint methodRid) { var list = GetRidList(tablesStream.MethodTable, methodRid, 5, tablesStream.ParamTable); if (list.Length == 0 || !hasParamPtr) { return(list); } var destTable = tablesStream.ParamTable; var newList = new RandomRidList((int)list.Length); for (uint i = 0; i < list.Length; i++) { var rid = ToParamRid(list[i]); if (destTable.IsInvalidRID(rid)) { continue; } newList.Add(rid); } return(newList); }
private void InitializeNestedClassesDictionary() { var table = tablesStream.NestedClassTable; var destTable = tablesStream.TypeDefTable; Dictionary <uint, bool> validTypeDefRids = null; var typeDefRidList = GetTypeDefRidList(); if (typeDefRidList.Length != destTable.Rows) { validTypeDefRids = new Dictionary <uint, bool>((int)typeDefRidList.Length); for (uint i = 0; i < typeDefRidList.Length; i++) { validTypeDefRids[typeDefRidList[i]] = true; } } var nestedRidsDict = new Dictionary <uint, bool>((int)table.Rows); var nestedRids = new List <uint>((int)table.Rows); // Need it so we add the rids in correct order for (uint rid = 1; rid <= table.Rows; rid++) { if (validTypeDefRids != null && !validTypeDefRids.ContainsKey(rid)) { continue; } var row = tablesStream.ReadNestedClassRow(rid); if (row == null) { continue; // Should never happen since rid is valid } if (!destTable.IsValidRID(row.NestedClass) || !destTable.IsValidRID(row.EnclosingClass)) { continue; } if (nestedRidsDict.ContainsKey(row.NestedClass)) { continue; } nestedRidsDict[row.NestedClass] = true; nestedRids.Add(row.NestedClass); } var newTypeDefRidToNestedClasses = new Dictionary <uint, RandomRidList>(); foreach (var nestedRid in nestedRids) { var row = tablesStream.ReadNestedClassRow(GetNestedClassRid(nestedRid)); if (row == null) { continue; } RandomRidList ridList; if (!newTypeDefRidToNestedClasses.TryGetValue(row.EnclosingClass, out ridList)) { newTypeDefRidToNestedClasses[row.EnclosingClass] = ridList = new RandomRidList(); } ridList.Add(nestedRid); } var newNonNestedTypes = new RandomRidList((int)(destTable.Rows - nestedRidsDict.Count)); for (uint rid = 1; rid <= destTable.Rows; rid++) { if (validTypeDefRids != null && !validTypeDefRids.ContainsKey(rid)) { continue; } if (nestedRidsDict.ContainsKey(rid)) { continue; } newNonNestedTypes.Add(rid); } Interlocked.CompareExchange(ref nonNestedTypes, newNonNestedTypes, null); // Initialize this one last since it's tested by the callers of this method Interlocked.CompareExchange(ref typeDefRidToNestedClasses, newTypeDefRidToNestedClasses, null); }