<commit_before>// dnlib: See LICENSE.txt for more info

using System;
using System.Collections.Generic;
using System.Diagnostics;
using dnlib.IO;
using dnlib.PE;
using dnlib.Threading;

namespace dnlib.DotNet.MD {
	/// <summary>
	/// Used when a #- stream is present in the metadata
	/// </summary>
	sealed class ENCMetadata : MetadataBase {
		static readonly UTF8String DeletedName = "_Deleted";
		bool hasMethodPtr, hasFieldPtr, hasParamPtr, hasEventPtr, hasPropertyPtr;
		bool hasDeletedRows;
		readonly CLRRuntimeReaderKind runtime;
		readonly Dictionary<Table, SortedTable> sortedTables = new Dictionary<Table, SortedTable>();
#if THREAD_SAFE
		readonly Lock theLock = Lock.Create();
#endif

		/// <inheritdoc/>
		public override bool IsCompressed => false;

		/// <inheritdoc/>
		public ENCMetadata(IPEImage peImage, ImageCor20Header cor20Header, MetadataHeader mdHeader, CLRRuntimeReaderKind runtime)
			: base(peImage, cor20Header, mdHeader) {
			this.runtime = runtime;
		}

		/// <inheritdoc/>
		internal ENCMetadata(MetadataHeader mdHeader, bool isStandalonePortablePdb, CLRRuntimeReaderKind runtime)
			: base(mdHeader, isStandalonePortablePdb) {
			this.runtime = runtime;
		}

		/// <inheritdoc/>
		protected override void InitializeInternal(DataReaderFactory mdReaderFactory, uint metadataBaseOffset) {
			DotNetStream dns = null;
			try {
				if (runtime == CLRRuntimeReaderKind.Mono) {
					var newAllStreams = new List<DotNetStream>(allStreams);
					for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--) {
						var sh = mdHeader.StreamHeaders[i];
						switch (sh.Name) {
						case "#Strings":
							if (stringsStream is null) {
								stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(stringsStream);
								continue;
							}
							break;

						case "#US":
							if (usStream is null) {
								usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(usStream);
								continue;
							}
							break;

						case "#Blob":
							if (blobStream is null) {
								blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(blobStream);
								continue;
							}
							break;

						case "#GUID":
							if (guidStream is null) {
								guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(guidStream);
								continue;
							}
							break;

						case "#~":
						case "#-":
							if (tablesStream is null) {
								tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime);
								newAllStreams.Add(tablesStream);
								continue;
							}
							break;

						case "#Pdb":
							if (isStandalonePortablePdb && pdbStream is null) {
								pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(pdbStream);
								continue;
							}
							break;
						}
						dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh);
						newAllStreams.Add(dns);
						dns = null;
					}
					newAllStreams.Reverse();
					allStreams = newAllStreams;
				}
				else {
					Debug.Assert(runtime == CLRRuntimeReaderKind.CLR);
					foreach (var sh in mdHeader.StreamHeaders) {
						switch (sh.Name.ToUpperInvariant()) {
						case "#STRINGS":
							if (stringsStream is null) {
								stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(stringsStream);
								continue;
							}
							break;

						case "#US":
							if (usStream is null) {
								usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(usStream);
								continue;
							}
							break;

						case "#BLOB":
							if (blobStream is null) {
								blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(blobStream);
								continue;
							}
							break;

						case "#GUID":
							if (guidStream is null) {
								guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(guidStream);
								continue;
							}
							break;

						case "#~":  // Only if #Schema is used
						case "#-":
							if (tablesStream is null) {
								tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime);
								allStreams.Add(tablesStream);
								continue;
							}
							break;

						case "#PDB":
							// Case sensitive comparison since it's a stream that's not read by the CLR,
							// only by other libraries eg. System.Reflection.Metadata.
							if (isStandalonePortablePdb && pdbStream is null && sh.Name == "#Pdb") {
								pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(pdbStream);
								continue;
							}
							break;
						}
						dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh);
						allStreams.Add(dns);
						dns = null;
					}
				}
			}
			finally {
				dns?.Dispose();
			}

			if (tablesStream is null)
				throw new BadImageFormatException("Missing MD stream");

			if (pdbStream is not null)
				tablesStream.Initialize(pdbStream.TypeSystemTableRows);
			else
				tablesStream.Initialize(null);

			// The pointer tables are used iff row count != 0
			hasFieldPtr = !tablesStream.FieldPtrTable.IsEmpty;
			hasMethodPtr = !tablesStream.MethodPtrTable.IsEmpty;
			hasParamPtr = !tablesStream.ParamPtrTable.IsEmpty;
			hasEventPtr = !tablesStream.EventPtrTable.IsEmpty;
			hasPropertyPtr = !tablesStream.PropertyPtrTable.IsEmpty;
			hasDeletedRows = tablesStream.HasDelete;
		}

		/// <inheritdoc/>
		public override RidList GetTypeDefRidList() {
			if (!hasDeletedRows)
				return base.GetTypeDefRidList();
			uint rows = tablesStream.TypeDefTable.Rows;
			var list = new List<uint>((int)rows);
			for (uint rid = 1; rid <= rows; rid++) {
				if (!tablesStream.TryReadTypeDefRow(rid, out var row))
					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.Name).StartsWith(DeletedName))
					continue;	// ignore this deleted row
				list.Add(rid);
			}
			return RidList.Create(list);
		}
<commit_msg>`TypeDef` with rid 1 can't be a deleted type<commit_after>// dnlib: See LICENSE.txt for more info

using System;
using System.Collections.Generic;
using System.Diagnostics;
using dnlib.IO;
using dnlib.PE;
using dnlib.Threading;

namespace dnlib.DotNet.MD {
	/// <summary>
	/// Used when a #- stream is present in the metadata
	/// </summary>
	sealed class ENCMetadata : MetadataBase {
		static readonly UTF8String DeletedName = "_Deleted";
		bool hasMethodPtr, hasFieldPtr, hasParamPtr, hasEventPtr, hasPropertyPtr;
		bool hasDeletedRows;
		readonly CLRRuntimeReaderKind runtime;
		readonly Dictionary<Table, SortedTable> sortedTables = new Dictionary<Table, SortedTable>();
#if THREAD_SAFE
		readonly Lock theLock = Lock.Create();
#endif

		/// <inheritdoc/>
		public override bool IsCompressed => false;

		/// <inheritdoc/>
		public ENCMetadata(IPEImage peImage, ImageCor20Header cor20Header, MetadataHeader mdHeader, CLRRuntimeReaderKind runtime)
			: base(peImage, cor20Header, mdHeader) {
			this.runtime = runtime;
		}

		/// <inheritdoc/>
		internal ENCMetadata(MetadataHeader mdHeader, bool isStandalonePortablePdb, CLRRuntimeReaderKind runtime)
			: base(mdHeader, isStandalonePortablePdb) {
			this.runtime = runtime;
		}

		/// <inheritdoc/>
		protected override void InitializeInternal(DataReaderFactory mdReaderFactory, uint metadataBaseOffset) {
			DotNetStream dns = null;
			try {
				if (runtime == CLRRuntimeReaderKind.Mono) {
					var newAllStreams = new List<DotNetStream>(allStreams);
					for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--) {
						var sh = mdHeader.StreamHeaders[i];
						switch (sh.Name) {
						case "#Strings":
							if (stringsStream is null) {
								stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(stringsStream);
								continue;
							}
							break;

						case "#US":
							if (usStream is null) {
								usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(usStream);
								continue;
							}
							break;

						case "#Blob":
							if (blobStream is null) {
								blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(blobStream);
								continue;
							}
							break;

						case "#GUID":
							if (guidStream is null) {
								guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(guidStream);
								continue;
							}
							break;

						case "#~":
						case "#-":
							if (tablesStream is null) {
								tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime);
								newAllStreams.Add(tablesStream);
								continue;
							}
							break;

						case "#Pdb":
							if (isStandalonePortablePdb && pdbStream is null) {
								pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh);
								newAllStreams.Add(pdbStream);
								continue;
							}
							break;
						}
						dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh);
						newAllStreams.Add(dns);
						dns = null;
					}
					newAllStreams.Reverse();
					allStreams = newAllStreams;
				}
				else {
					Debug.Assert(runtime == CLRRuntimeReaderKind.CLR);
					foreach (var sh in mdHeader.StreamHeaders) {
						switch (sh.Name.ToUpperInvariant()) {
						case "#STRINGS":
							if (stringsStream is null) {
								stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(stringsStream);
								continue;
							}
							break;

						case "#US":
							if (usStream is null) {
								usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(usStream);
								continue;
							}
							break;

						case "#BLOB":
							if (blobStream is null) {
								blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(blobStream);
								continue;
							}
							break;

						case "#GUID":
							if (guidStream is null) {
								guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(guidStream);
								continue;
							}
							break;

						case "#~":  // Only if #Schema is used
						case "#-":
							if (tablesStream is null) {
								tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime);
								allStreams.Add(tablesStream);
								continue;
							}
							break;

						case "#PDB":
							// Case sensitive comparison since it's a stream that's not read by the CLR,
							// only by other libraries eg. System.Reflection.Metadata.
							if (isStandalonePortablePdb && pdbStream is null && sh.Name == "#Pdb") {
								pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh);
								allStreams.Add(pdbStream);
								continue;
							}
							break;
						}
						dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh);
						allStreams.Add(dns);
						dns = null;
					}
				}
			}
			finally {
				dns?.Dispose();
			}

			if (tablesStream is null)
				throw new BadImageFormatException("Missing MD stream");

			if (pdbStream is not null)
				tablesStream.Initialize(pdbStream.TypeSystemTableRows);
			else
				tablesStream.Initialize(null);

			// The pointer tables are used iff row count != 0
			hasFieldPtr = !tablesStream.FieldPtrTable.IsEmpty;
			hasMethodPtr = !tablesStream.MethodPtrTable.IsEmpty;
			hasParamPtr = !tablesStream.ParamPtrTable.IsEmpty;
			hasEventPtr = !tablesStream.EventPtrTable.IsEmpty;
			hasPropertyPtr = !tablesStream.PropertyPtrTable.IsEmpty;
			hasDeletedRows = tablesStream.HasDelete;
		}

		/// <inheritdoc/>
		public override RidList GetTypeDefRidList() {
			if (!hasDeletedRows)
				return base.GetTypeDefRidList();
			uint rows = tablesStream.TypeDefTable.Rows;
			var list = new List<uint>((int)rows);
			for (uint rid = 1; rid <= rows; rid++) {
				if (!tablesStream.TryReadTypeDefRow(rid, out var row))
					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.
				// It's not possible to delete the global type (<Module>)
				if (rid != 1 && stringsStream.ReadNoNull(row.Name).StartsWith(DeletedName))
					continue;	// ignore this deleted row
				list.Add(rid);
			}
			return RidList.Create(list);
		}

{'fraction_non_alphanumeric': 0.10170027678924476, 'fraction_numerical': 0.0018979833926453143, 'mean_word_length': 2.787361485474693, 'pattern_counts': {'":': 28, '<': 28, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2618322', 'n_tokens_mistral': 5312, 'n_tokens_neox': 3757, 'n_words': 939}