public SigType GetSigType(TypeReference type) { string name = type.FullName; switch (name) { case Constants.Void : return new SigType (ElementType.Void); case Constants.Object : return new SigType (ElementType.Object); case Constants.Boolean : return new SigType (ElementType.Boolean); case Constants.String : return new SigType (ElementType.String); case Constants.Char : return new SigType (ElementType.Char); case Constants.SByte : return new SigType (ElementType.I1); case Constants.Byte : return new SigType (ElementType.U1); case Constants.Int16 : return new SigType (ElementType.I2); case Constants.UInt16 : return new SigType (ElementType.U2); case Constants.Int32 : return new SigType (ElementType.I4); case Constants.UInt32 : return new SigType (ElementType.U4); case Constants.Int64 : return new SigType (ElementType.I8); case Constants.UInt64 : return new SigType (ElementType.U8); case Constants.Single : return new SigType (ElementType.R4); case Constants.Double : return new SigType (ElementType.R8); case Constants.IntPtr : return new SigType (ElementType.I); case Constants.UIntPtr : return new SigType (ElementType.U); case Constants.TypedReference : return new SigType (ElementType.TypedByRef); } if (type is GenericParameter) { GenericParameter gp = type as GenericParameter; int pos = gp.Owner.GenericParameters.IndexOf (gp); if (gp.Owner is TypeReference) return new VAR (pos); else if (gp.Owner is MethodReference) return new MVAR (pos); else throw new ReflectionException ("Unkown generic parameter type"); } else if (type is GenericInstanceType) { GenericInstanceType git = type as GenericInstanceType; GENERICINST gi = new GENERICINST (); gi.ValueType = git.IsValueType; gi.Type = GetTypeDefOrRefToken (git.ElementType); gi.Signature = new GenericInstSignature (); gi.Signature.Arity = git.GenericArguments.Count; gi.Signature.Types = new SigType [gi.Signature.Arity]; for (int i = 0; i < git.GenericArguments.Count; i++) gi.Signature.Types [i] = GetSigType (git.GenericArguments [i]); return gi; } else if (type is ArrayType) { ArrayType aryType = type as ArrayType; if (aryType.IsSizedArray) { SZARRAY szary = new SZARRAY (); szary.Type = GetSigType (aryType.ElementType); return szary; } // not optimized ArrayShape shape = new ArrayShape (); shape.Rank = aryType.Dimensions.Count; shape.NumSizes = 0; for (int i = 0; i < shape.Rank; i++) { ArrayDimension dim = aryType.Dimensions [i]; if (dim.UpperBound > 0) shape.NumSizes++; } shape.Sizes = new int [shape.NumSizes]; shape.NumLoBounds = shape.Rank; shape.LoBounds = new int [shape.NumLoBounds]; for (int i = 0; i < shape.Rank; i++) { ArrayDimension dim = aryType.Dimensions [i]; shape.LoBounds [i] = dim.LowerBound; if (dim.UpperBound > 0) shape.Sizes [i] = dim.UpperBound - dim.LowerBound + 1; } ARRAY ary = new ARRAY (); ary.Shape = shape; ary.Type = GetSigType (aryType.ElementType); return ary; } else if (type is PointerType) { PTR p = new PTR (); TypeReference elementType = (type as PointerType).ElementType; p.Void = elementType.FullName == Constants.Void; if (!p.Void) { p.CustomMods = GetCustomMods (elementType); p.PtrType = GetSigType (elementType); } return p; } else if (type is FunctionPointerType) { throw new NotImplementedException ("Function pointer are not implemented"); // TODO } else if (type is TypeSpecification) { return GetSigType ((type as TypeSpecification).ElementType); } else if (type.IsValueType) { VALUETYPE vt = new VALUETYPE (); vt.Type = GetTypeDefOrRefToken (type); return vt; } else { CLASS c = new CLASS (); c.Type = GetTypeDefOrRefToken (type); return c; } }
void Write(SigType t) { Write((int)t.ElementType); switch (t.ElementType) { case ElementType.ValueType: Write((int)Utilities.CompressMetadataToken( CodedIndex.TypeDefOrRef, ((VALUETYPE)t).Type)); break; case ElementType.Class: Write((int)Utilities.CompressMetadataToken( CodedIndex.TypeDefOrRef, ((CLASS)t).Type)); break; case ElementType.Ptr: PTR p = (PTR)t; if (p.Void) { Write(ElementType.Void); } else { Write(p.CustomMods); Write(p.PtrType); } break; case ElementType.FnPtr: FNPTR fp = (FNPTR)t; if (fp.Method is MethodRefSig) { (fp.Method as MethodRefSig).Accept(this); } else { (fp.Method as MethodDefSig).Accept(this); } break; case ElementType.Array: ARRAY ary = (ARRAY)t; Write(ary.CustomMods); ArrayShape shape = ary.Shape; Write(ary.Type); Write(shape.Rank); Write(shape.NumSizes); foreach (int size in shape.Sizes) { Write(size); } Write(shape.NumLoBounds); foreach (int loBound in shape.LoBounds) { Write(loBound); } break; case ElementType.SzArray: SZARRAY sa = (SZARRAY)t; Write(sa.CustomMods); Write(sa.Type); break; case ElementType.Var: Write(((VAR)t).Index); break; case ElementType.MVar: Write(((MVAR)t).Index); break; case ElementType.GenericInst: GENERICINST gi = t as GENERICINST; Write(gi.ValueType ? ElementType.ValueType : ElementType.Class); Write((int)Utilities.CompressMetadataToken( CodedIndex.TypeDefOrRef, gi.Type)); Write(gi.Signature); break; } }
SigType ReadType(byte [] data, int pos, out int start) { start = pos; ElementType element = (ElementType)Utilities.ReadCompressedInteger(data, start, out start); switch (element) { case ElementType.ValueType: VALUETYPE vt = new VALUETYPE(); vt.Type = Utilities.GetMetadataToken(CodedIndex.TypeDefOrRef, (uint)Utilities.ReadCompressedInteger(data, start, out start)); return(vt); case ElementType.Class: CLASS c = new CLASS(); c.Type = Utilities.GetMetadataToken(CodedIndex.TypeDefOrRef, (uint)Utilities.ReadCompressedInteger(data, start, out start)); return(c); case ElementType.Ptr: PTR p = new PTR(); int buf = start; int flag = Utilities.ReadCompressedInteger(data, start, out start); p.Void = flag == (int)ElementType.Void; if (p.Void) { return(p); } start = buf; p.CustomMods = this.ReadCustomMods(data, start, out start); p.PtrType = this.ReadType(data, start, out start); return(p); case ElementType.FnPtr: FNPTR fp = new FNPTR(); if ((data [start] & 0x5) != 0) { MethodRefSig mr = new MethodRefSig((uint)start); ReadMethodRefSig(mr, data, start, out start); fp.Method = mr; } else { MethodDefSig md = new MethodDefSig((uint)start); ReadMethodDefSig(md, data, start, out start); fp.Method = md; } return(fp); case ElementType.Array: ARRAY ary = new ARRAY(); ArrayShape shape = new ArrayShape(); ary.Type = this.ReadType(data, start, out start); shape.Rank = Utilities.ReadCompressedInteger(data, start, out start); shape.NumSizes = Utilities.ReadCompressedInteger(data, start, out start); shape.Sizes = new int [shape.NumSizes]; for (int i = 0; i < shape.NumSizes; i++) { shape.Sizes [i] = Utilities.ReadCompressedInteger(data, start, out start); } shape.NumLoBounds = Utilities.ReadCompressedInteger(data, start, out start); shape.LoBounds = new int [shape.NumLoBounds]; for (int i = 0; i < shape.NumLoBounds; i++) { shape.LoBounds [i] = Utilities.ReadCompressedInteger(data, start, out start); } ary.Shape = shape; return(ary); case ElementType.SzArray: SZARRAY sa = new SZARRAY(); sa.Type = this.ReadType(data, start, out start); return(sa); case ElementType.Var: return(new VAR(Utilities.ReadCompressedInteger(data, start, out start))); case ElementType.MVar: return(new MVAR(Utilities.ReadCompressedInteger(data, start, out start))); case ElementType.GenericInst: GENERICINST ginst = new GENERICINST(); ginst.ValueType = ((ElementType)Utilities.ReadCompressedInteger( data, start, out start)) == ElementType.ValueType; ginst.Type = Utilities.GetMetadataToken(CodedIndex.TypeDefOrRef, (uint)Utilities.ReadCompressedInteger(data, start, out start)); ginst.Signature = ReadGenericInstSignature(data, start, out start); return(ginst); default: return(new SigType(element)); } }
SigType ReadType(byte [] data, int pos, out int start) { start = pos; ElementType element = (ElementType) Utilities.ReadCompressedInteger (data, start, out start); switch (element) { case ElementType.ValueType : VALUETYPE vt = new VALUETYPE (); vt.Type = Utilities.GetMetadataToken(CodedIndex.TypeDefOrRef, (uint) Utilities.ReadCompressedInteger (data, start, out start)); return vt; case ElementType.Class : CLASS c = new CLASS (); c.Type = Utilities.GetMetadataToken (CodedIndex.TypeDefOrRef, (uint) Utilities.ReadCompressedInteger (data, start, out start)); return c; case ElementType.Ptr : PTR p = new PTR (); int buf = start; int flag = Utilities.ReadCompressedInteger (data, start, out start); p.Void = flag == (int) ElementType.Void; if (p.Void) return p; start = buf; p.CustomMods = ReadCustomMods (data, start, out start); p.PtrType = ReadType (data, start, out start); return p; case ElementType.FnPtr : FNPTR fp = new FNPTR (); if ((data [start] & 0x5) != 0) { MethodRefSig mr = new MethodRefSig ((uint) start); ReadMethodRefSig (mr, data, start, out start); fp.Method = mr; } else { MethodDefSig md = new MethodDefSig ((uint) start); ReadMethodDefSig (md, data, start, out start); fp.Method = md; } return fp; case ElementType.Array : ARRAY ary = new ARRAY (); ary.CustomMods = ReadCustomMods (data, start, out start); ArrayShape shape = new ArrayShape (); ary.Type = ReadType (data, start, out start); shape.Rank = Utilities.ReadCompressedInteger (data, start, out start); shape.NumSizes = Utilities.ReadCompressedInteger (data, start, out start); shape.Sizes = new int [shape.NumSizes]; for (int i = 0; i < shape.NumSizes; i++) shape.Sizes [i] = Utilities.ReadCompressedInteger (data, start, out start); shape.NumLoBounds = Utilities.ReadCompressedInteger (data, start, out start); shape.LoBounds = new int [shape.NumLoBounds]; for (int i = 0; i < shape.NumLoBounds; i++) shape.LoBounds [i] = Utilities.ReadCompressedInteger (data, start, out start); ary.Shape = shape; return ary; case ElementType.SzArray : SZARRAY sa = new SZARRAY (); sa.CustomMods = ReadCustomMods (data, start, out start); sa.Type = ReadType (data, start, out start); return sa; case ElementType.Var: return new VAR (Utilities.ReadCompressedInteger (data, start, out start)); case ElementType.MVar: return new MVAR (Utilities.ReadCompressedInteger (data, start, out start)); case ElementType.GenericInst: GENERICINST ginst = new GENERICINST (); ginst.ValueType = ((ElementType) Utilities.ReadCompressedInteger ( data, start, out start)) == ElementType.ValueType; ginst.Type = Utilities.GetMetadataToken (CodedIndex.TypeDefOrRef, (uint) Utilities.ReadCompressedInteger (data, start, out start)); ginst.Signature = ReadGenericInstSignature (data, start, out start); return ginst; default : return new SigType (element); } }