internal ArrayType (TypeReference elementType, ArrayShape shape) : base (elementType)
		{
			m_dimensions = new ArrayDimensionCollection (this);
			for (int i = 0; i < shape.Rank; i++) {
				int lower = 0, upper = 0;
				if (i < shape.NumSizes)
					if (i < shape.NumLoBounds) {
						lower = shape.LoBounds [i];
						upper = shape.LoBounds [i] + shape.Sizes [i] - 1;
					} else
						upper = shape.Sizes [i] - 1;

				m_dimensions.Add (new ArrayDimension (lower, upper));
			}
		}
        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;
            }
        }
        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));
            }
        }
        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;
            }
        }
Beispiel #5
0
        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);
            }
        }