/// <summary> /// Loops through all type definitions in metadata, adding them to the given table /// </summary> private void PopulateTableWithTypeDefinitions(Dictionary <NamespaceDefinitionHandle, NamespaceDataBuilder> table) { DebugCorlib.Assert(table != null); foreach (var typeHandle in this.metadataReader.TypeDefinitions) { TypeDefinition type = this.metadataReader.GetTypeDefinition(typeHandle); if (type.Attributes.IsNested()) { continue; } NamespaceDefinitionHandle namespaceHandle = this.metadataReader.TypeDefTable.GetNamespace(typeHandle); NamespaceDataBuilder builder; if (table.TryGetValue(namespaceHandle, out builder)) { builder.TypeDefinitions.Add(typeHandle); } else { StringHandle name = GetSimpleName(namespaceHandle); string fullName = this.metadataReader.GetString(namespaceHandle); var newData = new NamespaceDataBuilder(namespaceHandle, name, fullName); newData.TypeDefinitions.Add(typeHandle); table.Add(namespaceHandle, newData); } } }
/// <summary> /// Loops through all type forwarders in metadata, adding them to the given table /// </summary> private void PopulateTableWithExportedTypes(Dictionary <NamespaceDefinitionHandle, NamespaceDataBuilder> table) { DebugCorlib.Assert(table != null); foreach (var exportedTypeHandle in this.metadataReader.ExportedTypes) { ExportedType exportedType = this.metadataReader.GetExportedType(exportedTypeHandle); if (exportedType.Implementation.Kind == HandleKind.ExportedType) { continue; // skip nested exported types. } NamespaceDefinitionHandle namespaceHandle = exportedType.Namespace; NamespaceDataBuilder builder; if (table.TryGetValue(namespaceHandle, out builder)) { builder.ExportedTypes.Add(exportedTypeHandle); } else { DebugCorlib.Assert(namespaceHandle.HasFullName); StringHandle simpleName = GetSimpleName(namespaceHandle); string fullName = this.metadataReader.GetString(namespaceHandle); var newData = new NamespaceDataBuilder(namespaceHandle, simpleName, fullName); newData.ExportedTypes.Add(exportedTypeHandle); table.Add(namespaceHandle, newData); } } }
/// <summary> /// Quick convenience method that handles linking together child + parent /// </summary> private void LinkChildDataToParentData(NamespaceDataBuilder child, NamespaceDataBuilder parent) { DebugCorlib.Assert(child != null && parent != null); DebugCorlib.Assert(!child.Handle.IsNil); child.Parent = parent.Handle; parent.Namespaces.Add(child.Handle); }
internal string GetFullName(NamespaceDefinitionHandle handle) { DebugCorlib.Assert(!handle.HasFullName); // we should not hit the cache in this case. NamespaceData data = GetNamespaceData(handle); return(data.FullName); }
internal static IDisposable CreateMemoryMap(Stream stream) { DebugCorlib.Assert(lazyIsAvailable.GetValueOrDefault()); try { return((IDisposable)lazyCreateFromFile.Invoke(null, new object[7] { stream, // fileStream null, // mapName LongZero, // capacity MemoryMappedFileAccess_Read, // access null, // memoryMappedFileSecurity HandleInheritability_None, // inheritability True, // leaveOpen })); } catch (MemberAccessException) { lazyIsAvailable = false; return(null); } catch (TargetInvocationException ex) { ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); throw; } }
internal BlobReader(MemoryBlock block) { DebugCorlib.Assert(BitConverter.IsLittleEndian && block.Length >= 0 && (block.Pointer != null || block.Length == 0)); this.block = block; this.currentPointer = block.Pointer; this.endPointer = block.Pointer + block.Length; }
private MethodDefTreatment GetMethodTreatmentFromCustomAttributes(MethodDefinitionHandle methodDef) { MethodDefTreatment treatment = 0; foreach (var caHandle in GetCustomAttributes(methodDef)) { StringHandle namespaceHandle, nameHandle; if (!GetAttributeTypeNameRaw(caHandle, out namespaceHandle, out nameHandle)) { continue; } DebugCorlib.Assert(!namespaceHandle.IsVirtual && !nameHandle.IsVirtual); if (StringStream.EqualsRaw(namespaceHandle, "Windows.UI.Xaml")) { if (StringStream.EqualsRaw(nameHandle, "TreatAsPublicMethodAttribute")) { treatment |= MethodDefTreatment.MarkPublicFlag; } if (StringStream.EqualsRaw(nameHandle, "TreatAsAbstractMethodAttribute")) { treatment |= MethodDefTreatment.MarkAbstractFlag; } } } return(treatment); }
internal CustomAttributeValueTreatment CalculateCustomAttributeValueTreatment(CustomAttributeHandle handle) { DebugCorlib.Assert(metadataKind != MetadataKind.Ecma335); var parent = CustomAttributeTable.GetParent(handle); // Check for Windows.Foundation.Metadata.AttributeUsageAttribute. // WinMD rules: // - The attribute is only applicable on TypeDefs. // - Constructor must be a MemberRef with TypeRef. if (!IsWindowsAttributeUsageAttribute(parent, handle)) { return(CustomAttributeValueTreatment.None); } var targetTypeDef = (TypeDefinitionHandle)parent; if (StringStream.EqualsRaw(TypeDefTable.GetNamespaceString(targetTypeDef), "Windows.Foundation.Metadata")) { if (StringStream.EqualsRaw(TypeDefTable.GetName(targetTypeDef), "VersionAttribute")) { return(CustomAttributeValueTreatment.AttributeUsageVersionAttribute); } if (StringStream.EqualsRaw(TypeDefTable.GetName(targetTypeDef), "DeprecatedAttribute")) { return(CustomAttributeValueTreatment.AttributeUsageDeprecatedAttribute); } } bool allowMultiple = HasAttribute(targetTypeDef, "Windows.Foundation.Metadata", "AllowMultipleAttribute"); return(allowMultiple ? CustomAttributeValueTreatment.AttributeUsageAllowMultiple : CustomAttributeValueTreatment.AttributeUsageAllowSingle); }
internal int CompareUtf8NullTerminatedStringWithAsciiString(int offset, string asciiString) { // Assumes stringAscii conly contains ASCII characters and no nil characters. CheckBounds(offset, 0); byte *p = Pointer + offset; int limit = Length - offset; for (int i = 0; i < asciiString.Length; i++) { DebugCorlib.Assert((int)asciiString[i] > 0 && (int)asciiString[i] <= 0x7f); if (i > limit) { // Heap value is shorter. return(-1); } if (*p != asciiString[i]) { // If we hit the end of the heap value (*p == 0) // the heap value is shorter than the string, so we return negative value. return(*p - asciiString[i]); } p++; } // Either the heap value name matches exactly the given string or // it is longer so it is considered "greater". return((*p == 0) ? 0 : +1); }
private static void AssertSorted(string[] keys) { for (int i = 0; i < keys.Length - 1; i++) { DebugCorlib.Assert(String.CompareOrdinal(keys[i], keys[i + 1]) < 0); } }
// comparison stops at null terminator, terminator parameter, or end-of-block -- whichever comes first. internal bool Utf8NullTermintatedStringStartsWithAsciiPrefix(int offset, string asciiPrefix) { // Assumes stringAscii conly contains ASCII characters and no nil characters. CheckBounds(offset, 0); // Make sure that we won't read beyond the block even if the block doesn't end with 0 byte. if (asciiPrefix.Length > Length - offset) { return(false); } byte *p = Pointer + offset; for (int i = 0; i < asciiPrefix.Length; i++) { DebugCorlib.Assert((int)asciiPrefix[i] > 0 && (int)asciiPrefix[i] <= 0x7f); if (asciiPrefix[i] != *p) { return(false); } p++; } return(true); }
/// <summary> /// Get number of bytes from offset to given terminator, null terminator, or end-of-block. /// (whichever comes first). returned length does not include the terminator, but numberOfBytesRead /// out paramater does. /// </summary> /// <param name="offset">Offset in to the block where the UTF8 bytes start.</param> /// <param name="terminator">A character in the ASCII range that marks the end of the string. /// If a value other than '\0' is passed we still stop at the null terminator if encountered first.</param> /// <param name="numberOfBytesRead">The number of bytes read, which includes the terminator if we did not hit the end of the block.</param> /// <returns>Length (byte count) not including terminator.</returns> internal int GetUtf8NullTerminatedLength(int offset, out int numberOfBytesRead, char terminator = '\0') { CheckBounds(offset, 0); DebugCorlib.Assert(terminator <= 0x7f); byte *start = Pointer + offset; byte *end = Pointer + Length; byte *current = start; while (current < end) { byte b = *current; if (b == 0 || b == terminator) { break; } current++; } int length = (int)(current - start); numberOfBytesRead = length; if (current < end) { // we also read the terminator numberOfBytesRead++; } return(length); }
private static string DecodeUtf8Prefixed(byte *bytes, int byteCount, byte[] prefix, MetadataStringDecoder utf8Decoder) { DebugCorlib.Assert(utf8Decoder != null); int prefixedByteCount = byteCount + prefix.Length; if (prefixedByteCount == 0) { return(String.Empty); } byte[] buffer = AcquireBuffer(prefixedByteCount); prefix.CopyTo(buffer, 0); Marshal.Copy((IntPtr)bytes, buffer, prefix.Length, byteCount); string result; fixed(byte *prefixedBytes = buffer) { result = utf8Decoder.GetString(prefixedBytes, prefixedByteCount); } ReleaseBuffer(buffer); return(result); }
private static unsafe string GetStringUsingCreateStringFromEncoding( String_CreateStringFromEncoding createStringFromEncoding, byte *bytes, int byteCount, Encoding encoding) { // String.CreateStringFromEncoding is an internal method that does not validate // arguments, but this implementation can leak publicly (by design) via // MetadataStringDecoder.GetString. Therefore, we implement the same validation // that Encoding.GetString would do if it were available directly. DebugCorlib.Assert(encoding != null); // validated by MetadataStringDecoder constructor. if (bytes == null) { throw new ArgumentNullException("bytes"); } if (byteCount < 0) { throw new ArgumentOutOfRangeException("byteCount"); } return(createStringFromEncoding(bytes, byteCount, encoding)); }
/// <summary> /// This will return a StringHandle for the simple name of a namespace name at the given segment index. /// If no segment index is passed explicitly or the "segment" index is greater than or equal to the number /// of segments, then the last segment is used. "Segment" in this context refers to part of a namespace /// name between dots. /// /// Example: Given a NamespaceDefinitionHandle to "System.Collections.Generic.Test" called 'handle': /// /// reader.GetString(GetSimpleName(handle)) == "Test" /// reader.GetString(GetSimpleName(handle, 0)) == "System" /// reader.GetString(GetSimpleName(handle, 1)) == "Collections" /// reader.GetString(GetSimpleName(handle, 2)) == "Generic" /// reader.GetString(GetSimpleName(handle, 3)) == "Test" /// reader.GetString(GetSimpleName(handle, 1000)) == "Test" /// </summary> private StringHandle GetSimpleName(NamespaceDefinitionHandle fullNamespaceHandle, int segmentIndex = Int32.MaxValue) { StringHandle handleContainingSegment = fullNamespaceHandle.GetFullName(); DebugCorlib.Assert(!handleContainingSegment.IsVirtual); int lastFoundIndex = fullNamespaceHandle.Index - 1; int currentSegment = 0; while (currentSegment < segmentIndex) { int currentIndex = this.metadataReader.StringStream.IndexOfRaw(lastFoundIndex + 1, '.'); if (currentIndex == -1) { break; } lastFoundIndex = currentIndex; ++currentSegment; } DebugCorlib.Assert(lastFoundIndex >= 0 || currentSegment == 0); // + 1 because lastFoundIndex will either "point" to a '.', or will be -1. Either way, // we want the next char. uint resultIndex = (uint)(lastFoundIndex + 1); return(StringHandle.FromIndex(resultIndex).WithDotTermination()); }
private StringHandle.VirtualIndex GetVirtualNameIndex(AssemblyReferenceHandle.VirtualIndex index) { switch (index) { case AssemblyReferenceHandle.VirtualIndex.System_ObjectModel: return(StringHandle.VirtualIndex.System_ObjectModel); case AssemblyReferenceHandle.VirtualIndex.System_Runtime: return(StringHandle.VirtualIndex.System_Runtime); case AssemblyReferenceHandle.VirtualIndex.System_Runtime_InteropServices_WindowsRuntime: return(StringHandle.VirtualIndex.System_Runtime_InteropServices_WindowsRuntime); case AssemblyReferenceHandle.VirtualIndex.System_Runtime_WindowsRuntime: return(StringHandle.VirtualIndex.System_Runtime_WindowsRuntime); case AssemblyReferenceHandle.VirtualIndex.System_Runtime_WindowsRuntime_UI_Xaml: return(StringHandle.VirtualIndex.System_Runtime_WindowsRuntime_UI_Xaml); case AssemblyReferenceHandle.VirtualIndex.System_Numerics_Vectors: return(StringHandle.VirtualIndex.System_Numerics_Vectors); } DebugCorlib.Assert(false, "Unexpected virtual index value"); return(0); }
internal string GetString(StringHandle handle, MetadataStringDecoder utf8Decoder) { int index = handle.Index; byte[] prefix; if (handle.IsVirtual) { switch (handle.StringKind) { case StringKind.Plain: return(virtualValues[index]); case StringKind.WinRTPrefixed: prefix = MetadataReader.WinRTPrefix; break; default: DebugCorlib.Assert(false, "We should not get here"); return(null); } } else { prefix = null; } int bytesRead; char otherTerminator = handle.StringKind == StringKind.DotTerminated ? '.' : '\0'; return(this.Block.PeekUtf8NullTerminated(index, prefix, utf8Decoder, out bytesRead, otherTerminator)); }
private static void AssertFilled() { for (int i = 0; i < virtualValues.Length; i++) { DebugCorlib.Assert(virtualValues[i] != null, "Missing virtual value for StringHandle.VirtualIndex." + (StringHandle.VirtualIndex)i); } }
internal Constant(MetadataReader reader, uint rowId) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(rowId != 0); this.reader = reader; this.rowId = rowId; }
internal EventDefinition(MetadataReader reader, EventDefinitionHandle handle) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(!handle.IsNil); this.reader = reader; this.rowId = handle.RowId; }
internal MethodSpecification(MetadataReader reader, MethodSpecificationHandle handle) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(!handle.IsNil); this.reader = reader; this.rowId = handle.RowId; }
internal GenericParameterConstraint(MetadataReader reader, GenericParameterConstraintHandle handle) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(!handle.IsNil); this.reader = reader; this.rowId = handle.RowId; }
internal MemberReference(MetadataReader reader, uint treatmentAndRowId) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(treatmentAndRowId != 0); this.reader = reader; this.treatmentAndRowId = treatmentAndRowId; }
internal DeclarativeSecurityAttribute(MetadataReader reader, uint rowId) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(rowId != 0); this.reader = reader; this.rowId = rowId; }
internal ExportedType(MetadataReader reader, uint rowId) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(rowId != 0); this.reader = reader; this.rowId = rowId; }
internal CustomAttribute(MetadataReader reader, uint treatmentAndRowId) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(treatmentAndRowId != 0); this.reader = reader; this.treatmentAndRowId = treatmentAndRowId; }
protected override void Dispose(bool disposing) { DebugCorlib.Assert(disposing); // we don't own the memory, just null out the pointer. memory = null; size = 0; }
internal MethodDefinition(MetadataReader reader, uint treatmentAndRowId) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(treatmentAndRowId != 0); this.reader = reader; this.treatmentAndRowId = treatmentAndRowId; }
internal StandaloneSignature(MetadataReader reader, StandaloneSignatureHandle handle) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(!handle.IsNil); this.reader = reader; this.rowId = handle.RowId; }
internal AssemblyFile(MetadataReader reader, AssemblyFileHandle handle) { DebugCorlib.Assert(reader != null); DebugCorlib.Assert(!handle.IsNil); this.reader = reader; this.rowId = handle.RowId; }