Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

664 lines
18 KiB
C#

//
// Utilities.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Generated by /CodeGen/cecil-gen.rb do not edit
// Sat Feb 16 23:23:29 +0100 2008
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Metadata {
using System;
using System.Collections;
using System.IO;
sealed class Utilities {
Utilities ()
{
}
public static int ReadCompressedInteger (byte [] data, int pos, out int start)
{
int integer;
start = pos;
if ((data [pos] & 0x80) == 0) {
integer = data [pos];
start++;
} else if ((data [pos] & 0x40) == 0) {
integer = (data [start] & ~0x80) << 8;
integer |= data [pos + 1];
start += 2;
} else {
integer = (data [start] & ~0xc0) << 24;
integer |= data [pos + 1] << 16;
integer |= data [pos + 2] << 8;
integer |= data [pos + 3];
start += 4;
}
return integer;
}
public static int ReadCompressedSignedInteger (byte [] data, int pos, out int start)
{
int integer = ReadCompressedInteger (data, pos, out start) >> 1;
if ((integer & 1) == 0)
return integer;
if (integer < 0x40)
return integer - 0x40;
if (integer < 0x2000)
return integer - 0x2000;
if (integer < 0x10000000)
return integer - 0x10000000;
return integer - 0x20000000;
}
public static int WriteCompressedInteger (BinaryWriter writer, int value)
{
if (value < 0x80)
writer.Write ((byte) value);
else if (value < 0x4000) {
writer.Write ((byte) (0x80 | (value >> 8)));
writer.Write ((byte) (value & 0xff));
} else {
writer.Write ((byte) ((value >> 24) | 0xc0));
writer.Write ((byte) ((value >> 16) & 0xff));
writer.Write ((byte) ((value >> 8) & 0xff));
writer.Write ((byte) (value & 0xff));
}
return (int) writer.BaseStream.Position;
}
public static MetadataToken GetMetadataToken (CodedIndex cidx, uint data)
{
uint rid = 0;
switch (cidx) {
case CodedIndex.TypeDefOrRef :
rid = data >> 2;
switch (data & 3) {
case 0 :
return new MetadataToken (TokenType.TypeDef, rid);
case 1 :
return new MetadataToken (TokenType.TypeRef, rid);
case 2 :
return new MetadataToken (TokenType.TypeSpec, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.HasConstant :
rid = data >> 2;
switch (data & 3) {
case 0 :
return new MetadataToken (TokenType.Field, rid);
case 1 :
return new MetadataToken (TokenType.Param, rid);
case 2 :
return new MetadataToken (TokenType.Property, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.HasCustomAttribute :
rid = data >> 5;
switch (data & 31) {
case 0 :
return new MetadataToken (TokenType.Method, rid);
case 1 :
return new MetadataToken (TokenType.Field, rid);
case 2 :
return new MetadataToken (TokenType.TypeRef, rid);
case 3 :
return new MetadataToken (TokenType.TypeDef, rid);
case 4 :
return new MetadataToken (TokenType.Param, rid);
case 5 :
return new MetadataToken (TokenType.InterfaceImpl, rid);
case 6 :
return new MetadataToken (TokenType.MemberRef, rid);
case 7 :
return new MetadataToken (TokenType.Module, rid);
case 8 :
return new MetadataToken (TokenType.Permission, rid);
case 9 :
return new MetadataToken (TokenType.Property, rid);
case 10 :
return new MetadataToken (TokenType.Event, rid);
case 11 :
return new MetadataToken (TokenType.Signature, rid);
case 12 :
return new MetadataToken (TokenType.ModuleRef, rid);
case 13 :
return new MetadataToken (TokenType.TypeSpec, rid);
case 14 :
return new MetadataToken (TokenType.Assembly, rid);
case 15 :
return new MetadataToken (TokenType.AssemblyRef, rid);
case 16 :
return new MetadataToken (TokenType.File, rid);
case 17 :
return new MetadataToken (TokenType.ExportedType, rid);
case 18 :
return new MetadataToken (TokenType.ManifestResource, rid);
case 19 :
return new MetadataToken (TokenType.GenericParam, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.HasFieldMarshal :
rid = data >> 1;
switch (data & 1) {
case 0 :
return new MetadataToken (TokenType.Field, rid);
case 1 :
return new MetadataToken (TokenType.Param, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.HasDeclSecurity :
rid = data >> 2;
switch (data & 3) {
case 0 :
return new MetadataToken (TokenType.TypeDef, rid);
case 1 :
return new MetadataToken (TokenType.Method, rid);
case 2 :
return new MetadataToken (TokenType.Assembly, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.MemberRefParent :
rid = data >> 3;
switch (data & 7) {
case 0 :
return new MetadataToken (TokenType.TypeDef, rid);
case 1 :
return new MetadataToken (TokenType.TypeRef, rid);
case 2 :
return new MetadataToken (TokenType.ModuleRef, rid);
case 3 :
return new MetadataToken (TokenType.Method, rid);
case 4 :
return new MetadataToken (TokenType.TypeSpec, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.HasSemantics :
rid = data >> 1;
switch (data & 1) {
case 0 :
return new MetadataToken (TokenType.Event, rid);
case 1 :
return new MetadataToken (TokenType.Property, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.MethodDefOrRef :
rid = data >> 1;
switch (data & 1) {
case 0 :
return new MetadataToken (TokenType.Method, rid);
case 1 :
return new MetadataToken (TokenType.MemberRef, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.MemberForwarded :
rid = data >> 1;
switch (data & 1) {
case 0 :
return new MetadataToken (TokenType.Field, rid);
case 1 :
return new MetadataToken (TokenType.Method, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.Implementation :
rid = data >> 2;
switch (data & 3) {
case 0 :
return new MetadataToken (TokenType.File, rid);
case 1 :
return new MetadataToken (TokenType.AssemblyRef, rid);
case 2 :
return new MetadataToken (TokenType.ExportedType, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.CustomAttributeType :
rid = data >> 3;
switch (data & 7) {
case 2 :
return new MetadataToken (TokenType.Method, rid);
case 3 :
return new MetadataToken (TokenType.MemberRef, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.ResolutionScope :
rid = data >> 2;
switch (data & 3) {
case 0 :
return new MetadataToken (TokenType.Module, rid);
case 1 :
return new MetadataToken (TokenType.ModuleRef, rid);
case 2 :
return new MetadataToken (TokenType.AssemblyRef, rid);
case 3 :
return new MetadataToken (TokenType.TypeRef, rid);
default :
return MetadataToken.Zero;
}
case CodedIndex.TypeOrMethodDef :
rid = data >> 1;
switch (data & 1) {
case 0 :
return new MetadataToken (TokenType.TypeDef, rid);
case 1 :
return new MetadataToken (TokenType.Method, rid);
default :
return MetadataToken.Zero;
}
default :
return MetadataToken.Zero;
}
}
public static uint CompressMetadataToken (CodedIndex cidx, MetadataToken token)
{
uint ret = 0;
if (token.RID == 0)
return ret;
switch (cidx) {
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 :
throw new MetadataFormatException("Non valid Token for TypeDefOrRef");
}
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 :
throw new MetadataFormatException("Non valid Token for HasConstant");
}
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;
default :
throw new MetadataFormatException("Non valid Token for HasCustomAttribute");
}
case CodedIndex.HasFieldMarshal :
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.Field :
return ret | 0;
case TokenType.Param :
return ret | 1;
default :
throw new MetadataFormatException("Non valid Token for HasFieldMarshal");
}
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 :
throw new MetadataFormatException("Non valid Token for HasDeclSecurity");
}
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 :
throw new MetadataFormatException("Non valid Token for MemberRefParent");
}
case CodedIndex.HasSemantics :
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.Event :
return ret | 0;
case TokenType.Property :
return ret | 1;
default :
throw new MetadataFormatException("Non valid Token for HasSemantics");
}
case CodedIndex.MethodDefOrRef :
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.Method :
return ret | 0;
case TokenType.MemberRef :
return ret | 1;
default :
throw new MetadataFormatException("Non valid Token for MethodDefOrRef");
}
case CodedIndex.MemberForwarded :
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.Field :
return ret | 0;
case TokenType.Method :
return ret | 1;
default :
throw new MetadataFormatException("Non valid Token for MemberForwarded");
}
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 :
throw new MetadataFormatException("Non valid Token for Implementation");
}
case CodedIndex.CustomAttributeType :
ret = token.RID << 3;
switch (token.TokenType) {
case TokenType.Method :
return ret | 2;
case TokenType.MemberRef :
return ret | 3;
default :
throw new MetadataFormatException("Non valid Token for CustomAttributeType");
}
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 :
throw new MetadataFormatException("Non valid Token for ResolutionScope");
}
case CodedIndex.TypeOrMethodDef :
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.TypeDef :
return ret | 0;
case TokenType.Method :
return ret | 1;
default :
throw new MetadataFormatException("Non valid Token for TypeOrMethodDef");
}
default :
throw new MetadataFormatException ("Non valid CodedIndex");
}
}
internal static Type GetCorrespondingTable (TokenType t)
{
switch (t) {
case TokenType.Assembly :
return typeof (AssemblyTable);
case TokenType.AssemblyRef :
return typeof (AssemblyRefTable);
case TokenType.CustomAttribute :
return typeof (CustomAttributeTable);
case TokenType.Event :
return typeof (EventTable);
case TokenType.ExportedType :
return typeof (ExportedTypeTable);
case TokenType.Field :
return typeof (FieldTable);
case TokenType.File :
return typeof (FileTable);
case TokenType.InterfaceImpl :
return typeof (InterfaceImplTable);
case TokenType.MemberRef :
return typeof (MemberRefTable);
case TokenType.Method :
return typeof (MethodTable);
case TokenType.Module :
return typeof (ModuleTable);
case TokenType.ModuleRef :
return typeof (ModuleRefTable);
case TokenType.Param :
return typeof (ParamTable);
case TokenType.Permission :
return typeof (DeclSecurityTable);
case TokenType.Property :
return typeof (PropertyTable);
case TokenType.Signature :
return typeof (StandAloneSigTable);
case TokenType.TypeDef :
return typeof (TypeDefTable);
case TokenType.TypeRef :
return typeof (TypeRefTable);
case TokenType.TypeSpec :
return typeof (TypeSpecTable);
default :
return null;
}
}
internal delegate int TableRowCounter (int rid);
internal static int GetCodedIndexSize (CodedIndex ci, TableRowCounter rowCounter, int [] codedIndexCache)
{
int bits = 0, max = 0, index = (int) ci;
if (codedIndexCache [index] != 0)
return codedIndexCache [index];
int res = 0;
int [] rids;
switch (ci) {
case CodedIndex.TypeDefOrRef :
bits = 2;
rids = new int [3];
rids [0] = TypeDefTable.RId;
rids [1] = TypeRefTable.RId;
rids [2] = TypeSpecTable.RId;
break;
case CodedIndex.HasConstant :
bits = 2;
rids = new int [3];
rids [0] = FieldTable.RId;
rids [1] = ParamTable.RId;
rids [2] = PropertyTable.RId;
break;
case CodedIndex.HasCustomAttribute :
bits = 5;
rids = new int [20];
rids [0] = MethodTable.RId;
rids [1] = FieldTable.RId;
rids [2] = TypeRefTable.RId;
rids [3] = TypeDefTable.RId;
rids [4] = ParamTable.RId;
rids [5] = InterfaceImplTable.RId;
rids [6] = MemberRefTable.RId;
rids [7] = ModuleTable.RId;
rids [8] = DeclSecurityTable.RId;
rids [9] = PropertyTable.RId;
rids [10] = EventTable.RId;
rids [11] = StandAloneSigTable.RId;
rids [12] = ModuleRefTable.RId;
rids [13] = TypeSpecTable.RId;
rids [14] = AssemblyTable.RId;
rids [15] = AssemblyRefTable.RId;
rids [16] = FileTable.RId;
rids [17] = ExportedTypeTable.RId;
rids [18] = ManifestResourceTable.RId;
rids [19] = GenericParamTable.RId;
break;
case CodedIndex.HasFieldMarshal :
bits = 1;
rids = new int [2];
rids [0] = FieldTable.RId;
rids [1] = ParamTable.RId;
break;
case CodedIndex.HasDeclSecurity :
bits = 2;
rids = new int [3];
rids [0] = TypeDefTable.RId;
rids [1] = MethodTable.RId;
rids [2] = AssemblyTable.RId;
break;
case CodedIndex.MemberRefParent :
bits = 3;
rids = new int [5];
rids [0] = TypeDefTable.RId;
rids [1] = TypeRefTable.RId;
rids [2] = ModuleRefTable.RId;
rids [3] = MethodTable.RId;
rids [4] = TypeSpecTable.RId;
break;
case CodedIndex.HasSemantics :
bits = 1;
rids = new int [2];
rids [0] = EventTable.RId;
rids [1] = PropertyTable.RId;
break;
case CodedIndex.MethodDefOrRef :
bits = 1;
rids = new int [2];
rids [0] = MethodTable.RId;
rids [1] = MemberRefTable.RId;
break;
case CodedIndex.MemberForwarded :
bits = 1;
rids = new int [2];
rids [0] = FieldTable.RId;
rids [1] = MethodTable.RId;
break;
case CodedIndex.Implementation :
bits = 2;
rids = new int [3];
rids [0] = FileTable.RId;
rids [1] = AssemblyRefTable.RId;
rids [2] = ExportedTypeTable.RId;
break;
case CodedIndex.CustomAttributeType :
bits = 3;
rids = new int [2];
rids [0] = MethodTable.RId;
rids [1] = MemberRefTable.RId;
break;
case CodedIndex.ResolutionScope :
bits = 2;
rids = new int [4];
rids [0] = ModuleTable.RId;
rids [1] = ModuleRefTable.RId;
rids [2] = AssemblyRefTable.RId;
rids [3] = TypeRefTable.RId;
break;
case CodedIndex.TypeOrMethodDef :
bits = 1;
rids = new int [2];
rids [0] = TypeDefTable.RId;
rids [1] = MethodTable.RId;
break;
default :
throw new MetadataFormatException ("Non valid CodedIndex");
}
for (int i = 0; i < rids.Length; i++) {
int rows = rowCounter (rids [i]);
if (rows > max) max = rows;
}
res = max < (1 << (16 - bits)) ? 2 : 4;
codedIndexCache [index] = res;
return res;
}
}
}