// // Author: // Jb Evain (jbevain@gmail.com) // // Copyright (c) 2008 - 2015 Jb Evain // Copyright (c) 2008 - 2011 Novell, Inc. // // Licensed under the MIT/X11 license. // using MonoFN.Cecil.Metadata; using System; namespace MonoFN.Cecil { static partial class Mixin { public const int TableCount = 58; public const int CodedIndexCount = 14; public static uint ReadCompressedUInt32 (this byte [] data, ref int position) { uint integer; if ((data [position] & 0x80) == 0) { integer = data [position]; position++; } else if ((data [position] & 0x40) == 0) { integer = (uint)(data [position] & ~0x80) << 8; integer |= data [position + 1]; position += 2; } else { integer = (uint)(data [position] & ~0xc0) << 24; integer |= (uint)data [position + 1] << 16; integer |= (uint)data [position + 2] << 8; integer |= (uint)data [position + 3]; position += 4; } return integer; } public static MetadataToken GetMetadataToken (this CodedIndex self, uint data) { uint rid; TokenType token_type; switch (self) { case CodedIndex.TypeDefOrRef: rid = data >> 2; switch (data & 3) { case 0: token_type = TokenType.TypeDef; goto ret; case 1: token_type = TokenType.TypeRef; goto ret; case 2: token_type = TokenType.TypeSpec; goto ret; default: goto exit; } case CodedIndex.HasConstant: rid = data >> 2; switch (data & 3) { case 0: token_type = TokenType.Field; goto ret; case 1: token_type = TokenType.Param; goto ret; case 2: token_type = TokenType.Property; goto ret; default: goto exit; } case CodedIndex.HasCustomAttribute: rid = data >> 5; switch (data & 31) { case 0: token_type = TokenType.Method; goto ret; case 1: token_type = TokenType.Field; goto ret; case 2: token_type = TokenType.TypeRef; goto ret; case 3: token_type = TokenType.TypeDef; goto ret; case 4: token_type = TokenType.Param; goto ret; case 5: token_type = TokenType.InterfaceImpl; goto ret; case 6: token_type = TokenType.MemberRef; goto ret; case 7: token_type = TokenType.Module; goto ret; case 8: token_type = TokenType.Permission; goto ret; case 9: token_type = TokenType.Property; goto ret; case 10: token_type = TokenType.Event; goto ret; case 11: token_type = TokenType.Signature; goto ret; case 12: token_type = TokenType.ModuleRef; goto ret; case 13: token_type = TokenType.TypeSpec; goto ret; case 14: token_type = TokenType.Assembly; goto ret; case 15: token_type = TokenType.AssemblyRef; goto ret; case 16: token_type = TokenType.File; goto ret; case 17: token_type = TokenType.ExportedType; goto ret; case 18: token_type = TokenType.ManifestResource; goto ret; case 19: token_type = TokenType.GenericParam; goto ret; case 20: token_type = TokenType.GenericParamConstraint; goto ret; case 21: token_type = TokenType.MethodSpec; goto ret; default: goto exit; } case CodedIndex.HasFieldMarshal: rid = data >> 1; switch (data & 1) { case 0: token_type = TokenType.Field; goto ret; case 1: token_type = TokenType.Param; goto ret; default: goto exit; } case CodedIndex.HasDeclSecurity: rid = data >> 2; switch (data & 3) { case 0: token_type = TokenType.TypeDef; goto ret; case 1: token_type = TokenType.Method; goto ret; case 2: token_type = TokenType.Assembly; goto ret; default: goto exit; } case CodedIndex.MemberRefParent: rid = data >> 3; switch (data & 7) { case 0: token_type = TokenType.TypeDef; goto ret; case 1: token_type = TokenType.TypeRef; goto ret; case 2: token_type = TokenType.ModuleRef; goto ret; case 3: token_type = TokenType.Method; goto ret; case 4: token_type = TokenType.TypeSpec; goto ret; default: goto exit; } case CodedIndex.HasSemantics: rid = data >> 1; switch (data & 1) { case 0: token_type = TokenType.Event; goto ret; case 1: token_type = TokenType.Property; goto ret; default: goto exit; } case CodedIndex.MethodDefOrRef: rid = data >> 1; switch (data & 1) { case 0: token_type = TokenType.Method; goto ret; case 1: token_type = TokenType.MemberRef; goto ret; default: goto exit; } case CodedIndex.MemberForwarded: rid = data >> 1; switch (data & 1) { case 0: token_type = TokenType.Field; goto ret; case 1: token_type = TokenType.Method; goto ret; default: goto exit; } case CodedIndex.Implementation: rid = data >> 2; switch (data & 3) { case 0: token_type = TokenType.File; goto ret; case 1: token_type = TokenType.AssemblyRef; goto ret; case 2: token_type = TokenType.ExportedType; goto ret; default: goto exit; } case CodedIndex.CustomAttributeType: rid = data >> 3; switch (data & 7) { case 2: token_type = TokenType.Method; goto ret; case 3: token_type = TokenType.MemberRef; goto ret; default: goto exit; } case CodedIndex.ResolutionScope: rid = data >> 2; switch (data & 3) { case 0: token_type = TokenType.Module; goto ret; case 1: token_type = TokenType.ModuleRef; goto ret; case 2: token_type = TokenType.AssemblyRef; goto ret; case 3: token_type = TokenType.TypeRef; goto ret; default: goto exit; } case CodedIndex.TypeOrMethodDef: rid = data >> 1; switch (data & 1) { case 0: token_type = TokenType.TypeDef; goto ret; case 1: token_type = TokenType.Method; goto ret; default: goto exit; } case CodedIndex.HasCustomDebugInformation: rid = data >> 5; switch (data & 31) { case 0: token_type = TokenType.Method; goto ret; case 1: token_type = TokenType.Field; goto ret; case 2: token_type = TokenType.TypeRef; goto ret; case 3: token_type = TokenType.TypeDef; goto ret; case 4: token_type = TokenType.Param; goto ret; case 5: token_type = TokenType.InterfaceImpl; goto ret; case 6: token_type = TokenType.MemberRef; goto ret; case 7: token_type = TokenType.Module; goto ret; case 8: token_type = TokenType.Permission; goto ret; case 9: token_type = TokenType.Property; goto ret; case 10: token_type = TokenType.Event; goto ret; case 11: token_type = TokenType.Signature; goto ret; case 12: token_type = TokenType.ModuleRef; goto ret; case 13: token_type = TokenType.TypeSpec; goto ret; case 14: token_type = TokenType.Assembly; goto ret; case 15: token_type = TokenType.AssemblyRef; goto ret; case 16: token_type = TokenType.File; goto ret; case 17: token_type = TokenType.ExportedType; goto ret; case 18: token_type = TokenType.ManifestResource; goto ret; case 19: token_type = TokenType.GenericParam; goto ret; case 20: token_type = TokenType.GenericParamConstraint; goto ret; case 21: token_type = TokenType.MethodSpec; goto ret; case 22: token_type = TokenType.Document; goto ret; case 23: token_type = TokenType.LocalScope; goto ret; case 24: token_type = TokenType.LocalVariable; goto ret; case 25: token_type = TokenType.LocalConstant; goto ret; case 26: token_type = TokenType.ImportScope; goto ret; default: goto exit; } default: goto exit; } ret: return new MetadataToken (token_type, rid); exit: return MetadataToken.Zero; } public static uint CompressMetadataToken (this CodedIndex self, MetadataToken token) { uint ret = 0; if (token.RID == 0) return ret; switch (self) { case CodedIndex.TypeDefOrRef: ret = token.RID << 2; switch (token.TokenType) { case TokenType.TypeDef: return ret | 0; case TokenType.TypeRef: return ret | 1; case TokenType.TypeSpec: return ret | 2; default: goto exit; } case CodedIndex.HasConstant: ret = token.RID << 2; switch (token.TokenType) { case TokenType.Field: return ret | 0; case TokenType.Param: return ret | 1; case TokenType.Property: return ret | 2; default: goto exit; } case CodedIndex.HasCustomAttribute: ret = token.RID << 5; switch (token.TokenType) { case TokenType.Method: return ret | 0; case TokenType.Field: return ret | 1; case TokenType.TypeRef: return ret | 2; case TokenType.TypeDef: return ret | 3; case TokenType.Param: return ret | 4; case TokenType.InterfaceImpl: return ret | 5; case TokenType.MemberRef: return ret | 6; case TokenType.Module: return ret | 7; case TokenType.Permission: return ret | 8; case TokenType.Property: return ret | 9; case TokenType.Event: return ret | 10; case TokenType.Signature: return ret | 11; case TokenType.ModuleRef: return ret | 12; case TokenType.TypeSpec: return ret | 13; case TokenType.Assembly: return ret | 14; case TokenType.AssemblyRef: return ret | 15; case TokenType.File: return ret | 16; case TokenType.ExportedType: return ret | 17; case TokenType.ManifestResource: return ret | 18; case TokenType.GenericParam: return ret | 19; case TokenType.GenericParamConstraint: return ret | 20; case TokenType.MethodSpec: return ret | 21; default: goto exit; } case CodedIndex.HasFieldMarshal: ret = token.RID << 1; switch (token.TokenType) { case TokenType.Field: return ret | 0; case TokenType.Param: return ret | 1; default: goto exit; } case CodedIndex.HasDeclSecurity: ret = token.RID << 2; switch (token.TokenType) { case TokenType.TypeDef: return ret | 0; case TokenType.Method: return ret | 1; case TokenType.Assembly: return ret | 2; default: goto exit; } case CodedIndex.MemberRefParent: ret = token.RID << 3; switch (token.TokenType) { case TokenType.TypeDef: return ret | 0; case TokenType.TypeRef: return ret | 1; case TokenType.ModuleRef: return ret | 2; case TokenType.Method: return ret | 3; case TokenType.TypeSpec: return ret | 4; default: goto exit; } case CodedIndex.HasSemantics: ret = token.RID << 1; switch (token.TokenType) { case TokenType.Event: return ret | 0; case TokenType.Property: return ret | 1; default: goto exit; } case CodedIndex.MethodDefOrRef: ret = token.RID << 1; switch (token.TokenType) { case TokenType.Method: return ret | 0; case TokenType.MemberRef: return ret | 1; default: goto exit; } case CodedIndex.MemberForwarded: ret = token.RID << 1; switch (token.TokenType) { case TokenType.Field: return ret | 0; case TokenType.Method: return ret | 1; default: goto exit; } case CodedIndex.Implementation: ret = token.RID << 2; switch (token.TokenType) { case TokenType.File: return ret | 0; case TokenType.AssemblyRef: return ret | 1; case TokenType.ExportedType: return ret | 2; default: goto exit; } case CodedIndex.CustomAttributeType: ret = token.RID << 3; switch (token.TokenType) { case TokenType.Method: return ret | 2; case TokenType.MemberRef: return ret | 3; default: goto exit; } case CodedIndex.ResolutionScope: ret = token.RID << 2; switch (token.TokenType) { case TokenType.Module: return ret | 0; case TokenType.ModuleRef: return ret | 1; case TokenType.AssemblyRef: return ret | 2; case TokenType.TypeRef: return ret | 3; default: goto exit; } case CodedIndex.TypeOrMethodDef: ret = token.RID << 1; switch (token.TokenType) { case TokenType.TypeDef: return ret | 0; case TokenType.Method: return ret | 1; default: goto exit; } case CodedIndex.HasCustomDebugInformation: ret = token.RID << 5; switch (token.TokenType) { case TokenType.Method: return ret | 0; case TokenType.Field: return ret | 1; case TokenType.TypeRef: return ret | 2; case TokenType.TypeDef: return ret | 3; case TokenType.Param: return ret | 4; case TokenType.InterfaceImpl: return ret | 5; case TokenType.MemberRef: return ret | 6; case TokenType.Module: return ret | 7; case TokenType.Permission: return ret | 8; case TokenType.Property: return ret | 9; case TokenType.Event: return ret | 10; case TokenType.Signature: return ret | 11; case TokenType.ModuleRef: return ret | 12; case TokenType.TypeSpec: return ret | 13; case TokenType.Assembly: return ret | 14; case TokenType.AssemblyRef: return ret | 15; case TokenType.File: return ret | 16; case TokenType.ExportedType: return ret | 17; case TokenType.ManifestResource: return ret | 18; case TokenType.GenericParam: return ret | 19; case TokenType.GenericParamConstraint: return ret | 20; case TokenType.MethodSpec: return ret | 21; case TokenType.Document: return ret | 22; case TokenType.LocalScope: return ret | 23; case TokenType.LocalVariable: return ret | 24; case TokenType.LocalConstant: return ret | 25; case TokenType.ImportScope: return ret | 26; default: goto exit; } default: goto exit; } exit: throw new ArgumentException (); } public static int GetSize (this CodedIndex self, Func