public virtual Differences VisitSecurityAttributeList(SecurityAttributeList list1, SecurityAttributeList list2, out SecurityAttributeList changes, out SecurityAttributeList deletions, out SecurityAttributeList insertions){ changes = list1 == null ? null : list1.Clone(); deletions = list1 == null ? null : list1.Clone(); insertions = list1 == null ? new SecurityAttributeList() : list1.Clone(); //^ assert insertions != null; Differences differences = new Differences(); for (int j = 0, n = list2 == null ? 0 : list2.Count; j < n; j++){ //^ assert list2 != null; SecurityAttribute nd2 = list2[j]; if (nd2 == null) continue; insertions.Add(null); } TrivialHashtable savedDifferencesMapFor = this.differencesMapFor; this.differencesMapFor = null; TrivialHashtable matchedNodes = new TrivialHashtable(); for (int i = 0, k = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){ //^ assert list1 != null && changes != null && deletions != null; SecurityAttribute nd1 = list1[i]; if (nd1 == null) continue; Differences diff; int j; SecurityAttribute nd2 = this.GetClosestMatch(nd1, list1, list2, i, ref k, matchedNodes, out diff, out j); if (nd2 == null || diff == null){Debug.Assert(nd2 == null && diff == null); continue;} matchedNodes[nd1.UniqueKey] = nd1; matchedNodes[nd2.UniqueKey] = nd2; changes[i] = diff.Changes as SecurityAttribute; deletions[i] = diff.Deletions as SecurityAttribute; insertions[i] = diff.Insertions as SecurityAttribute; insertions[n+j] = nd1; //Records the position of nd2 in list2 in case the change involved a permutation Debug.Assert(diff.Changes == changes[i] && diff.Deletions == deletions[i] && diff.Insertions == insertions[i]); differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; } //Find deletions for (int i = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){ //^ assert list1 != null; SecurityAttribute nd1 = list1[i]; if (nd1 == null) continue; if (matchedNodes[nd1.UniqueKey] != null) continue; if (changes != null) changes[i] = null; if (deletions != null) deletions[i] = nd1; insertions[i] = null; differences.NumberOfDifferences += 1; } //Find insertions for (int j = 0, n = list1 == null ? 0 : list1.Count, m = list2 == null ? 0 : list2.Count; j < m; j++){ //^ assert list2 != null; SecurityAttribute nd2 = list2[j]; if (nd2 == null) continue; if (matchedNodes[nd2.UniqueKey] != null) continue; insertions[n+j] = nd2; //Records nd2 as an insertion into list1, along with its position in list2 differences.NumberOfDifferences += 1; //REVIEW: put the size of the tree here? } if (differences.NumberOfDifferences == 0){ changes = null; deletions = null; insertions = null; } this.differencesMapFor = savedDifferencesMapFor; return differences; }
private SecurityAttributeList GetSecurityAttributesFor(int parentIndex) { DeclSecurityRow[] securityAttributes = this.tables.DeclSecurityTable; SecurityAttributeList attributes = new SecurityAttributeList(); try { int i = 0, n = securityAttributes.Length, j = n - 1; if (n == 0) return attributes; bool sorted = (this.sortedTablesMask >> (int)TableIndices.DeclSecurity) % 2 == 1; if (sorted) { while (i < j) { int k = (i + j) / 2; if (securityAttributes[k].Parent < parentIndex) i = k + 1; else j = k; } while (i > 0 && securityAttributes[i - 1].Parent == parentIndex) i--; } for (; i < n; i++) if (securityAttributes[i].Parent == parentIndex) attributes.Add(this.GetSecurityAttribute(i)); else if (sorted) break; } catch (Exception e) { if (this.module == null) return attributes; if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList(); this.module.MetadataImportErrors.Add(e); } return attributes; }